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

signalk-ewelink

v1.0.4

Published

eWeLink/Sonoff devices as native Signal K — LAN-first, cloud-fallback, push not poll, live power. No MQTT.

Readme

signalk-ewelink

eWeLink/Sonoff devices as native Signal K — no MQTT broker, no external control plugin, no .env. One self-contained plugin that is the bridge to the hardware, configured entirely in the Signal K admin UI.

What it does

  • LAN-first, cloud-fallback, by discovery. If mDNS finds a device on the server's network, its state and control go direct over the encrypted eWeLink LAN protocol — no internet involved. A device it has not discovered routes to the eWeLink cloud instead. Discovery can also undiscover (an mDNS goodbye or repeated poll misses) and the cloud takes over seamlessly. In practice that means switches keep working when the boat is offline, and still work when you are away from it.
  • Push, not poll. State arrives the moment it changes — mDNS updates on LAN, the eWeLink WebSocket on cloud (including changes made from the eWeLink app or a device's physical button). A slow reconcile poll only backstops missed pushes.
  • Live power. For energy-metering plugs (POWR3 and friends) the plugin sends the device's uiActive streaming nudge, so power/voltage/current update every few seconds instead of freezing between the device's own lazy reports.
  • Native PUT control. Registers a Signal K PUT handler per switch path, so any client or dashboard sets ….state and the plugin drives the relay. No separate control plugin.

Requirements

  • A Signal K node server.
  • python3 on the server host, with the packages in requirements.txt (pycryptodome, zeroconf, websocket-client). See Python deps.
  • For LAN control, the Signal K host must share a network with the devices — mDNS does not cross subnets, so a container needs host networking.
  • An eWeLink account, and an OAuth app from dev.ewelink.cc (free). Cloud access is what supplies the device list and the per-device LAN keys, so it is needed at least once even for a LAN-only setup.

Install

From the Signal K Appstore (search for signalk-ewelink), or by hand:

cd ~/.signalk/node_modules
npm install signalk-ewelink

Then restart the server and enable the plugin in Server → Plugin Config.

Python deps

The worker is Python, so install its dependencies against the same python3 the Signal K server runs:

python3 -m pip install -r requirements.txt

On modern Debian/Raspberry Pi OS that needs a venv or pip install --break-system-packages. Alternatively, vendor them inside the plugin directory, which keeps the plugin self-contained:

cd ~/.signalk/node_modules/signalk-ewelink
python3 -m pip install --target vendor/ -r requirements.txt

Note that the official Signal K docker image ships without python3.

Configure (Signal K admin UI)

1. Create an eWeLink OAuth app

At dev.ewelink.cc, create an app and note its App ID and App secret. Register a Redirect URL for it — your Signal K server's address (e.g. http://localhost:3000/) works fine; nothing has to be listening there, it is only where the browser lands.

2. Enter credentials and authorise

In the plugin config, fill in App ID, App secret, Region (eu, us, as, cn — the region your eWeLink account was created in) and the Redirect URL you registered. Save.

eWeLink's OAuth is a browser login, so it needs one manual step. Check the Signal K server log: the plugin prints a login URL. Open it, sign in to eWeLink and approve. Your browser is redirected to your Redirect URL with ?code=… on the end. Copy that code out of the address bar, paste it into the plugin's Authorisation code field and save again.

That is a one-time step. The plugin exchanges the code for tokens, stores them, and refreshes them by itself from then on. You can clear the code field afterwards. Authorisation codes are single-use and expire within minutes — if it fails, reload the login URL and get a fresh one.

3. Pick your devices

Reopen the config page. The Device dropdown is now populated by discovery (your cloud device list plus anything mDNS sees). For each device you want in Signal K, add an entry and set:

  • Device — pick from the dropdown.
  • Kindsingle for a one-relay device, multi for a multi-gang switch.
  • Channels — for multi, how many relays.
  • Signal K path — the base path to publish under, e.g. electrical.switches.shorepower.

A single device publishes <path>.state (and .power, .voltage, .current if it meters). A multi publishes <path>.chN.state per channel plus <path>.online. All switch paths accept PUT.

Device LAN keys are fetched from the cloud and cached automatically — there is no keys file to manage, and LAN control keeps working offline afterwards.

Where state is stored

Tokens (_tokens.json), the device key cache (_keycache.json) and the discovery list (discovered.json) are written to the Signal K plugin data directory, not into the plugin install. That means upgrading or reinstalling the plugin does not lose your authorisation. A Token file config option can override the token location if you need it elsewhere.

Troubleshooting

The plugin's status line in the admin UI says what is missing, and the server log carries the detail.

| Symptom | Cause | | --- | --- | | "No eWeLink credentials" | App ID/App secret not set yet. | | "Not authorised" | Credentials set, but the code step is not done — see the login URL in the log. | | Code exchange refused | The code was reused or expired, or the Redirect URL does not match the one registered at dev.ewelink.cc. | | Devices work from cloud but never LAN | mDNS is not reaching the server — check host networking, and that server and devices share a subnet. | | plugin.py exited in the log | Python dependencies missing; see Python deps. |

With no credentials at all, the plugin still starts and simply does nothing but listen — it does not crash the server.

Architecture

A thin index.js (the official sk-plugin-python-demo pattern) spawns plugin.py, pipes its stdout — one Signal K delta per line — into app.handleMessage, feeds config on stdin, and forwards PUTs to the child. All eWeLink logic (LAN AES + mDNS, OAuth, WebSocket push, uiActive streaming, discovery routing) lives in plugin.py.

License

MIT — see LICENSE.