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

@minguyen68/node-red-contrib-tapo-local

v0.3.1

Published

Node-RED node for local control of Tapo C225 cameras — no cloud, no extra deps

Readme

node-red-contrib-tapo-local

npm npm GitHub last commit

Node-RED node for local control of Tapo C225 cameras — no cloud required

Tested with: Tapo C225 (firmware 1.2.x). May work with other Tapo cameras that use the same local HTTPS API.


Nodes

tapo-device (config node)

Registers a camera. Select it from any tapo-c225 node.

| Field | Description | |----------|-------------| | Name | Optional display label | | IP | Camera's local IP address, e.g. 192.168.1.100 | | Username | admin | | Password | Camera account password — find it in Tapo app → Settings → Advanced → Camera Account (may differ from your TP-Link cloud password) |


tapo-c225

Sends a command to the camera when triggered by any input message.

Node settings:

| Field | Description | |---------|-------------| | Device | Select a tapo-device config node | | Command | Default command to run (see table below) |

Override at runtime — set msg.command before triggering:

{ "command": "privacy-off" }

Available commands:

| msg.command | Description | |---|---| | Privacy | | | get-lens-mask | Read current lens mask state — msg.payload.result.lens_mask.lens_mask_info.enabled is "on" or "off" | | privacy-on | Cover the lens (privacy mode on) | | privacy-off | Uncover the lens | | Alarm | | | alarm-on | Enable alarm on detected events (sound + light) | | alarm-off | Disable alarm on detected events | | alarm-trigger | Immediately sound siren + light (manual trigger) | | alarm-stop | Stop a manually triggered alarm | | Motion & AI detection | | | motion-on | Enable motion detection | | motion-off | Disable motion detection | | person-on | Enable AI person detection | | person-off | Disable AI person detection | | pet-on | Enable pet detection | | pet-off | Disable pet detection | | vehicle-on | Enable vehicle detection | | vehicle-off | Disable vehicle detection | | linecross-on | Enable line crossing detection | | linecross-off | Disable line crossing detection | | tamper-on | Enable camera tamper detection | | tamper-off | Disable camera tamper detection | | tracking-on | Enable auto-tracking (pan/tilt follows subject) | | tracking-off | Disable auto-tracking | | Sound detection | | | baby-cry-on | Enable baby cry detection | | baby-cry-off | Disable baby cry detection | | glass-break-on | Enable glass break detection | | glass-break-off | Disable glass break detection | | bark-on | Enable dog bark detection | | bark-off | Disable dog bark detection | | meow-on | Enable cat meow detection | | meow-off | Disable cat meow detection | | Camera | | | led-on | Turn the status LED on | | led-off | Turn the status LED off | | night-vision-on | Night vision always-on (IR active) | | night-vision-off | Night vision off (always day mode) | | night-vision-auto | Night vision auto-switch | | System | | | reboot | Reboot the camera | | Monitor | | | get-detections | Poll recent detection events — see below |

Output msg.payload:

{ "command": "privacy-on", "result": {} }

Polling detection events (get-detections)

Set msg.command = 'get-detections' and optionally msg.minutes = 10 (default 5) before triggering the node. msg.payload.events will be an array of detection objects from the camera's local event log:

{ "command": "get-detections", "events": [
  { "start_time": 1747300000, "end_time": 1747300010, "cls_type": "person", ... },
  { "start_time": 1747299900, "end_time": 1747299905, "cls_type": "baby_cry", ... }
]}

Detection types reported by C225: motion, person, vehicle, pet, baby_cry, glass_break, and others depending on firmware.

Requires: SD card inserted + local recording enabled in the Tapo app. If not present the node returns an empty events array.


Adding commands

Open lib/tapo-client.js and append an entry to COMMANDS. No other file changes needed unless you want the command in the editor dropdown (nodes/tapo-local.html).

const COMMANDS = {
    // _direct: false (default) → wrapped in multipleRequest (pytapo executeFunction path)
    // _direct: true            → sent as-is (pytapo performRequest path, for method:'set'/'do')

    'my-command': { method: 'someMethod', params: { ... } },
};

tapo-onvif-events — live event subscription

Subscribes to ONVIF WS-PullPoint events from the camera — no onvif npm library, implemented directly via raw HTTP SOAP calls.

Node settings

| Field | Description | |---|---| | Device | Select a tapo-device config node | | ONVIF port | Camera's ONVIF port (default 2020 for Tapo cameras) | | Action | Fixed action, or leave blank to use msg.action at runtime | | Poll hold | How long the camera holds each PullMessages request before returning empty (default 5 s) | | Motion timeout | Silence duration before emitting detected:false — must be longer than the camera's batch interval (~14 s on C225). Default 30 s |

Input

| msg.action | Description | |---|---| | "start" | Subscribe and begin delivering events | | "stop" | Send ONVIF Unsubscribe to camera and halt all requests |

Output msg.payload

{
  "topic":    "RuleEngine/PeopleDetector/People",
  "payload": {
    "detected": true,
    "time":     "2026-05-18T12:03:01Z",
    "property": "Initialized",
    "source":   { "Rule": "MyPeopleDetectorRule" },
    "data":     { "IsMotion": "true" }
  }
}

detected: false is emitted after motionTimeout seconds of camera silence (watchdog).


Adding commands

Open lib/tapo-client.js and append an entry to COMMANDS. No other file changes needed unless you want the command in the editor dropdown (nodes/tapo-local.html).

const COMMANDS = {
    // _direct: false (default) → wrapped in multipleRequest (pytapo executeFunction path)
    // _direct: true            → sent as-is (pytapo performRequest path, for method:'set'/'do')

    'my-command': { method: 'someMethod', params: { ... } },
};

CLI utility

scripts/tapo_privacy.js is a standalone Node.js script for testing from the command line (no deps):

node scripts/tapo_privacy.js <ip> <username> <password> <command>

# Examples:
node scripts/tapo_privacy.js 192.168.1.100 admin mypassword privacy-off
node scripts/tapo_privacy.js 192.168.1.100 admin mypassword reboot

License

MIT