Board v2 · Firmware in developmentDraft

upan.js

The planned browser library served by the device at /lib/upan.js for apps on the device — connection, login, units and an API sketch.

View .mdllms.txt

upan.js is a small browser library that the device itself serves at /lib/upan.js. It is meant for web apps stored on the device: it finds the API on the same origin, logs in, takes control, converts units, repeats jog frames, and turns device refusals into JavaScript errors. Its version follows the network module firmware, so an app always gets the library that matches the device it runs on.

Warning: upan.js is planned. The network module firmware that serves it is not written yet. The API below is a sketch and not final.

What it handles for you

  • Connection. Uses location.origin, because the app is loaded from the device. Never hard-code an address.
  • Login. Runs the challenge-response login from the Network API and asks for the password when there is no session. It includes its own SHA-256, HMAC and PBKDF2, because crypto.subtle is not available on plain http:// pages.
  • Control. Takes and releases control ownership over the WebSocket.
  • Units. The API speaks integer µm and millidegrees. The convenience methods take millimetres, inches or degrees, chosen with upan.units.
  • Jog. Repeats jog frames on its own while a jog is active, so the device keeps moving only while your page is alive.
  • Errors. A refusal from the motion MCU becomes an UpanError with code and limit_violation in the chosen units.

API sketch

const upan = await UPAN.connect();            // location.origin; asks for the password if there is no session
upan.units = "mm";                            // "mm" | "in" | "deg" — for the convenience methods only
await upan.acquireControl();
await upan.home();
await upan.moveRel(150);                      // 150 mm → 150000 µm inside
upan.jog(20);                                 // mm/s; the library repeats the frame
upan.jog(0);                                  // smooth stop
upan.stop();  upan.estop();
upan.onTelemetry(t => { /* … */ }, { hz: 20 }); // t.position in the chosen units, t.raw in base units
upan.onEvent(e => { /* … */ });
await upan.runProgram({ repeat: 1, instructions: [ /* … */ ] });
await upan.setOutput(0, true);

runProgram takes the program format of the network API, with protocol instructions in base units; see Programs over REST.

Handling refusals

try {
  await upan.moveRel(500);
} catch (e) {
  // e.code, e.g. "ERROR_LIMIT_EXCEEDED"
  // e.limit_violation: limit, requested and allowed value in the chosen units
  alert(e.message);
}

The library does not check limits itself. The motion MCU does, and its answer is passed through.

Status

Method names, argument order and the error object are not final yet. A full example panel is on Web apps on the device.