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

sense-node

v2.0.0

Published

Unofficial Node client for the Sense home energy monitor — realtime watts, trends, devices, with MFA/TOTP auth and token refresh.

Readme

sense-node

Unofficial Node client for the Sense home energy monitor — the same api.sense.com REST API and clientrt.sense.com realtime websocket the Sense apps use.

  • Realtime power — total watts, per-device watts, voltage, solar.
  • 📈 Trends — day/week/month/year/billing-cycle usage history.
  • 🔐 MFA/TOTP auth — finish 2FA manually, or auto-generate codes from a secret.
  • ♻️ Token refresh — renews the access token automatically on expiry.
  • 🪶 One dependency (ws); native fetch otherwise. Node ≥ 18.

⚠️ Unofficial and unsupported by Sense. Uses undocumented endpoints that can change without notice. Sense rate-limits the realtime websocket — sample a few frames and close (this library does that for you); don't hold it open.

Install

npm install sense-node

Quick start (library)

const Sense = require('sense-node')
const sense = new Sense({ email: '[email protected]', password: 'secret' })

// Auth once — tokens cache to ~/.sense-node/state.json and refresh on expiry.
try {
  await sense.authenticate()
} catch (e) {
  if (e.name === 'SenseMFARequiredError') {
    await sense.validateMFA('123456')   // code from your authenticator app
  } else throw e
}

// Realtime snapshot (samples a few frames, then closes the socket):
console.log(await sense.getRealtime())
// → { watts: 1148, voltage: [120, 120.1], hz: 60, solarWatts: 0,
//     devices: [ { name: 'AC', watts: 900 }, { name: 'Fridge', watts: 120 }, … ],
//     raw: { … } }

// Trends:
console.log(await sense.getTrends('DAY'))   // DAY | WEEK | MONTH | YEAR | CYCLE

Automatic MFA (headless / cron)

Pass the base32 TOTP secret (shown when you set up 2FA — not a 6-digit code) and the client generates and submits codes itself:

const sense = new Sense({ email, password, mfaSecret: 'JBSWY3DPEHPK3PXP' })
await sense.authenticate()   // handles MFA with no interaction

Quick start (CLI)

export [email protected] SENSE_PASSWORD=secret
# optional: export SENSE_MFA_SECRET=JBSWY3DPEHPK3PXP   (base32, for auto-MFA)

sense auth                 # authenticate (or: sense auth mfa <code>)
sense now                  # ⚡ 1148W now — AC 900W, Fridge 120W, …
sense now --json           # full realtime snapshot
sense trends WEEK          # usage history
sense devices              # discovered devices
sense status               # cached auth state

CLI env vars: SENSE_EMAIL, SENSE_PASSWORD, SENSE_MFA_SECRET, SENSE_STATE (token-file path), SENSE_VERBOSE=1.

API

| Method | Returns | Notes | | --- | --- | --- | | new Sense({ email, password, mfaSecret?, statePath?, tokenStore?, verbose? }) | — | state defaults to ~/.sense-node/state.json | | authenticate(email?, password?) | true | throws SenseMFARequiredError if 2FA needed and no mfaSecret | | validateMFA(code) | true | complete 2FA after the error above | | renewAuth() | true | refresh the access token (done automatically on 401/403) | | isAuthorized() | boolean | | | getRealtime({ samples?, timeoutMs? }) | snapshot | watts, voltage, hz, solarWatts, devices[] | | getTrends(scale?, start?) | object | scale: DAY/WEEK/MONTH/YEAR/CYCLE | | getDevices() / getMonitorOverview() / getMonitorStatus() | object | | | getDailyUsage(scale?, start?) | object | back-compat: trends + live currentConsumption |

Custom token storage

Pass any object with get(key) / set(key, value) as tokenStore to keep tokens somewhere other than a file (DB, secrets manager, etc.).

Migrating from v1

  • axios + moment are gone (native fetch + Date); only ws remains.
  • The trends endpoint moved to app/monitors/{id}/history/usagegetTrends() uses it. getDailyUsage(scale, start) is kept for compatibility.
  • New: mfaSecret/validateMFA (MFA didn't exist in v1), renewAuth, a cached token store, and a sense CLI.

License

MIT © Noel Portugal