Plain-language helper math: smoothing, calibration, PID and thermostat control, trend and surge prediction, rolling windows, kinematics, and geo. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
npm install @pamoja/kit
This pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.
The test that runs in CI, spliced here as it ran.
From bindings/node/guides/kit.ts:
import { Calibration, Median, Thermostat } from '@pamoja/kit'
// A 4-20 mA process loop carries the level as a current: 4 mA is empty and 20 mA is full,
// so the span is 16 mA and mid-scale is 12 mA, not 10.
const level = Calibration.twoPoint(4, 0, 20, 100)
console.log(`12 mA is ${level.apply(12)}% full, 4 mA is ${level.apply(4)}%`)
// The live zero is what makes a broken loop detectable: 0 mA is off the bottom of the
// scale rather than an empty tank.
const broken = level.apply(0)
console.log(`a dead loop reads ${broken}%, which is not a level at all`)
// A median window drops that sample outright, where an average would blend a quarter of
// the range into every reading after it.
const filtered = new Median()
let percent = 0
for (const milliamps of [12, 12, 0, 12, 12]) {
percent = level.apply(filtered.update(milliamps))
}
console.log(`through the dropout, the level held at ${percent}%`)
// A refill pump runs when the level falls below the deadband, which is the direction
// heating names; nothing about it is specific to temperature. The deadband stops a level
// sitting on the threshold from chattering the contactor.
const pump = Thermostat.heating(50, 10)
for (const reading of [percent, 38, 45, 62]) {
console.log(`at ${reading}% the pump is ${pump.update(reading) ? 'on' : 'off'}`)
}
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-kit |
reference, docs.rs, install |
| TypeScript | @pamoja/kit |
reference, install |
| Python | pamoja-kit |
reference, install |
| C# | Pamoja.Kit |
reference, install |
@pamoja/kit reference, every class, function, and type this package exports.MIT
Ergonomic facade over the generated helper-math binding.
The helpers are named for the goal rather than the technique, with the real algorithm one layer down: smooth a noisy reading, hold a value with a PID, warn before a tank runs dry, and notice when a tracked point leaves its area.
They are synchronous and allocation-free in the core, so the facade re-exports the generated classes rather than wrapping them; the one addition is a runtime Boundary object, because the generated enum is types-only.