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

webserial-scale

v1.1.0

Published

TypeScript library to read weighing scales (Toledo, Filizola, Elgin, Magna) through the Web Serial API.

Readme

webserial-scale

TypeScript library to read weighing scales (balanças) from the browser through the Web Serial API. Works in Chromium-based browsers (Chrome, Edge) over HTTPS or localhost.

Supported scales

| Protocol | Frame / request | Source studied | | ----------- | ------------------------------------------------------------ | ----------------------------------- | | toledo | STX 01234 ETX (kg × 1000), live STX 00.250 CR, request 0x05 | OpenAC.Net.Balanca, PesoLib, balance-app | | filizola | STX 01234 ETX, request 0x05 | OpenAC.Net.Balanca, PesoLib | | elgin | STX IIIIII ETX (status), STX [ -]00.250 ETX (weight), request 0x05 | PesoLib | | magna | PESO 1,328 kg\r\n, request P | PesoLib | | urano | ESC T1/ESC T2 frames (46, 69 and POP 56 bytes), request 0x04 | PesoLib |

Default serial settings for all protocols: 9600 baud, 8 data bits, no parity, 1 stop bit, no flow control.

Not implemented yet: Alfa 3101C. The PesoLib implementation has a buffer copy bug, so it needs a fresh review against the manual in docs/.

Usage

import { WebSerialScale } from "webserial-scale";

const scale = new WebSerialScale({ protocol: "toledo" });

scale.on("reading", (reading) => {
  if (reading.status === "stable") {
    console.log(`Stable: ${reading.weight} kg`);
  } else {
    console.log(`Scale status: ${reading.status}`);
  }
});
scale.on("error", (error) => console.error(error));
scale.on("disconnect", () => console.log("Scale disconnected"));

// Must run inside a user gesture (e.g. a click handler): shows the browser port picker.
button.addEventListener("click", () => scale.connect());

Connect to a port you already have (e.g. one returned by a previous requestPort()):

const port = await WebSerialScale.requestPort();
await scale.connect(port);

Options

new WebSerialScale({
  protocol: "filizola",                    // built-in name or a custom ScaleProtocol
  serial: { baudRate: 4800 },              // override any serial setting
  autoRequest: 250,                        // ms between weight requests; false = listen only
});
  • autoRequest defaults to 250 ms for request-driven protocols and is ignored for streaming-only ones. Use false for scales that stream continuously.
  • requestWeight() sends the request once, on demand.

Readings

Each reading has:

  • status: "stable" | "unstable" | "negative" | "overload"
  • weight: kilograms, or null when the scale sent no value (unstable, negative, overload)
  • unit: always "kg"
  • protocol, raw (the frame bytes), timestamp

Finding scales automatically

findCompatibleScales() probes the ports the user already authorized and returns the ones where a supported scale answered. The UI can list them and let the user pick one:

import { WebSerialScale } from "webserial-scale";

// 1. The user authorizes a port (once per port).
await WebSerialScale.requestPort();

// 2. Probe all authorized ports (takes a few seconds per port).
const found = await WebSerialScale.findCompatible();
// found: [{ port, protocol, serial, readings, sample, usb }, ...]

// 3. Connect to the one the user picked, with the serial settings that worked.
const item = found[0];
const scale = new WebSerialScale({ protocol: item.protocol, serial: item.serial });
await scale.connect(item.port);

Each port is opened with every serial configuration of the built-in protocols (for example 9600 8N1 and 9600 8N2), and the weight requests are sent while listening. Only authorized ports are probed, but the probe writes request bytes to them.

Decoding without a browser

FrameDecoder works on any byte stream (for example, data coming from Node's serialport package):

import { FrameDecoder, toledo } from "webserial-scale";

const decoder = new FrameDecoder(toledo);
for (const reading of decoder.push(chunk)) {
  console.log(reading.weight);
}

Protocol reference

See docs/PROTOCOLS.md for the frames of each scale, which ones send automatically, which need a request, and which need the operator to press a key.

Custom protocols

A protocol is an object with name, serialOptions, an optional requestCommand and a parseFrame(buffer) function that returns ok (with the frame length), incomplete or invalid. See src/protocols/ for examples.

Development

npm install
npm run typecheck
npm test
npm run build

Tests use the built-in node:test runner and need no browser or hardware. Testing with a real scale still requires a serial port or a virtual COM pair (e.g. com0com on Windows).

Credits

Protocol behaviour was derived from studying these projects:

Toledo Prix 3 Fit

Prix3Fit is the class for the Toledo Prix 3 Fit: reading in the four weight modes, price per kg, tare and pre-packing. See docs/PRIX3_FIT.md.

import { Prix3Fit } from "webserial-scale";

const fit = new Prix3Fit({ mode: "prt5" }); // same mode and baud rate as the scale's C14 and C16
await fit.connect(); // inside a user gesture
await fit.setPricePerKg(16.58);
await fit.setTare(360);
const reading = await fit.readWeight();
console.log(reading.weight, reading.status);

License

MIT. See LICENSE.