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

violet-poolcontroller

v0.1.0

Published

Asynchronous TypeScript client for the Violet Pool Controller HTTP API.

Readme

Violet Pool Controller

Node.js TypeScript CI License: AGPL v3+

An asynchronous, typed Node.js client for the Violet Pool Controller HTTP API.

This is the Node.js counterpart of violet-poolController-api. It supports Node.js 24 or newer and ships ESM, CommonJS, and TypeScript declarations.

Installation

npm install violet-poolcontroller

Usage

import { VioletPoolClient, VioletPoolError } from "violet-poolcontroller";

const client = new VioletPoolClient({
  host: "192.0.2.10",
  username: "admin",
  password: "secret",
});

try {
  const readings = await client.getReadings();
  console.log(readings.ph, readings.orp, readings.pump);

  await client.setPumpSpeed(2);
  await client.setDeviceTemperature("HEATER", 28.5);
} catch (error) {
  if (error instanceof VioletPoolError) {
    console.error(error.code, error.message);
  }
} finally {
  await client.close();
}

host accepts a hostname or IP address with an optional port. HTTP is used by default. Enable HTTPS explicitly:

const client = new VioletPoolClient({
  host: "pool-controller.example.test",
  useSsl: true,
  verifySsl: true,
});

Disabling certificate verification is supported for trusted networks with self-signed certificates, but weakens transport security:

const client = new VioletPoolClient({
  host: "192.0.2.10",
  useSsl: true,
  verifySsl: false,
});

Typed readings

getReadings() returns an immutable VioletReadings snapshot. Typed accessors coexist with raw firmware fields:

const readings = await client.getReadings();

console.log(readings.ph);
console.log(readings.pumpRuntimeMilliseconds);
console.log(readings.onewireTemperatures[1]);
console.log(readings.get("firmware_specific_key"));
console.log(readings.raw);

The client automatically normalizes both controller response formats:

  • base-module object responses;
  • dosing-standalone list responses.

Relay keys for absent extension modules are removed using the module alive-counter fields.

Dosing standalone

const client = new VioletPoolClient({
  host: "192.0.2.10",
  dosingStandalone: true,
});

await client.manualDosing("Chlor", 120);

The response format also updates client.dosingStandalone automatically. Base-module functions are rejected in standalone mode.

Safety acknowledgements

Cover movement requires the same explicit acknowledgement as the Python reference client:

await client.setCoverCommand("OPEN", { acknowledgeUnsafe: true });

Do not expose these calls without physical safety controls and independent monitoring.

Resilience

The client includes:

  • Basic Authentication;
  • request timeouts and cancellation;
  • bounded retry with exponential backoff and jitter;
  • Retry-After support for HTTP 429;
  • a circuit breaker for transient communication failures;
  • an independent token-bucket rate limiter per client, with optional explicit sharing;
  • strict host, endpoint, configuration-key, and setpoint validation;
  • separate error classes for authentication, timeout, payload, range, and unsafe-operation errors.

HTTP 4xx responses fail immediately. They are not retried and do not count toward the circuit breaker. Network errors, timeouts, HTTP 429, and HTTP 5xx responses are retryable. Retry timing matches the Python default of 1 second with exponential backoff and a 30-second cap. GET and HEAD requests are retried by default; non-idempotent POST requests are not, except for configuration writes explicitly marked retryable by the reference client.

Pass a RateLimiter when multiple clients should intentionally share one request budget:

import { RateLimiter, VioletPoolClient } from "violet-poolcontroller";

const rateLimiter = new RateLimiter();
const first = new VioletPoolClient({ host: "192.0.2.10", rateLimiter });
const second = new VioletPoolClient({ host: "192.0.2.11", rateLimiter });

Development

npm ci
npm run lint
npm run typecheck
npm test
npm run test:coverage
npm run build
npm pack --dry-run

The tests use a local stateful Node.js mock server and do not require controller hardware.

Upstream parity

The Python package is the source of truth. parity/upstream.json records the reviewed upstream commit and its Python-to-TypeScript name mapping. The parity check extracts the public contract from a clean Python checkout and verifies:

  • every public VioletPoolAPI member and package export;
  • all controller endpoint paths and action constants;
  • the complete controller error-code catalog;
  • the reviewed upstream commit and package version.

GitHub Actions checks the current Python main branch on every push and once per day. If upstream changes, CI fails until the TypeScript implementation, tests, and parity manifest are updated together. Run the same guard locally after building:

npm run parity:check -- --upstream-dir ../violet-poolController-api

Use a clean checkout of the Python repository for this command.

See PORTING_MATRIX.md for the Python-to-TypeScript API mapping and current port status.

License

GNU Affero General Public License v3.0 or later.

This is an unofficial community project. It is not affiliated with, endorsed by, or associated with PoolDigital GmbH & Co. KG. VIOLET and related trademarks belong to their respective owners.

Safety warning

This software controls physical equipment and water chemistry. Incorrect commands, invalid configuration, network failures, or software defects can cause unsafe water conditions, equipment damage, injury, or property loss. Monitor pool chemistry and hardware independently. Use this software at your own risk.