@pamoja/profile
v0.1.18
Published
Named, ready-to-run device profiles from plain data or a JSON manifest.
Readme
@pamoja/profile
Named, ready-to-run device profiles from plain data or a JSON manifest. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
Install
npm install @pamoja/profileThis pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.
Example
The test that runs in CI, spliced here as it ran.
From bindings/node/guides/profile.ts:
import { AlertKind, ControlKind, Profile, Viz } from '@pamoja/profile'
// A profile is plain data, so a fleet ships one as a file rather than as code. The two
// power thresholds are optional and fall back to the documented defaults.
const manifest = `{
"name": "brooder-heater",
"topic": "poultry/brooder/temperature",
"control": {
"kind": "setpoint", "setpoint": 32.0, "hysteresis": 0.5,
"cooling": false, "safe_band": 4.0
},
"power": { "active_secs": 120, "saver_secs": 600, "critical_secs": 1800 }
}`
const profile = Profile.fromJson(manifest)
console.log(`${profile.name} reports on ${profile.topic}`)
console.log(`wakes every ${profile.power.activeSecs}s while the battery is healthy`)
console.log(`saver mode below ${(profile.power.saverBelow * 100).toFixed(0)}% charge`)
// The manifest is the whole control loop. At 27.5 C the reading is below the deadband, so
// the lamp switches on, and it is more than 4 C from target, so the chicks are cold.
const cold = profile.controller().evaluate(27.5)
console.log(`at 27.5 C: lamp ${cold.actuator}, alert ${cold.alert?.kind}`)
// Back inside the deadband the lamp is left as it was, and nothing is raised.
const settled = profile.controller().evaluate(32.2)
console.log(`at 32.2 C: lamp ${settled.actuator}, alert ${settled.alert}`)
// Serializing writes the defaulted fields out in full, so a profile edited on a device and
// shared back carries no value the next reader has to infer.
const shared = profile.toJson()
console.log(`shared form names its defaults: ${shared.includes('saver_below')}`)
// The manifest also carries how a dashboard draws the node: one element here, the
// brooder's temperature as a thermometer with the band the chicks are safe in.
const drawn = profile.withPresentation({
elements: [
{
key: 'brooder_temperature',
unit: 'celsius',
label: 'Brooder temperature',
viz: Viz.Thermometer,
band: [28, 36],
},
],
})
const element = drawn.presentation?.elements[0]
console.log(
`draws ${element?.key} in ${element?.unit} with a safe band of ${element?.band?.[0]} to ${element?.band?.[1]}`,
)The same capability in every language
| Language | Package | Reference |
| --- | --- | --- |
| Rust | pamoja-profile | reference, docs.rs, install |
| TypeScript | @pamoja/profile | reference, install |
| Python | pamoja-profile | reference, install |
| C# | Pamoja.Profile | reference, install |
Documentation
@pamoja/profilereference, every class, function, and type this package exports.- The Device profiles guide, with the same example in Rust, Python, and C#.
- Every capability, and the install page.
License
MIT
