Commands
Control device outputs — vibration, rotation, position, and more
await device.vibrate(50);All output commands on a Device are async and accept integer values within the device's feature range (typically 0 to 100, except position durations which are in milliseconds). The valid range is defined per-feature in device.features.outputs. Values are rounded and clamped to the feature range automatically. Commands throw a DeviceError if the device lacks the required capability.
Scalar Commands
The scalar commands -- vibrate(), oscillate(), constrict(), spray(), temperature(), and led() -- share the same signature. Pass a single number to set all motors/actuators uniformly, or a FeatureValue[] to address each one individually.
// All motors at 75%
await device.vibrate(75);
// Per-motor control: motor 0 at 50%, motor 1 at 100%
await device.vibrate([
{ index: 0, value: 50 },
{ index: 1, value: 100 },
]);Each scalar type maps to an output type: vibrate() sends Vibrate, oscillate() sends Oscillate, and so on. Check support with device.canOutput("Vibrate") before calling.
Rotation
rotate() has two overloads. The simple form takes a speed and an optional direction. The array form addresses each motor independently with a RotationValue[].
// All motors at 60%, clockwise (default)
await device.rotate(60);
// Counterclockwise
await device.rotate(60, { clockwise: false });
// Per-motor: different speeds and directions
await device.rotate([
{ index: 0, speed: 50, clockwise: true },
{ index: 1, speed: 80, clockwise: false },
]);The client automatically selects RotateWithDirection when the device supports it, falling back to Rotate otherwise. Use device.canRotate to check support.
Position
position() moves linear axes to a target position over a specified duration. The duration parameter is required for the uniform overload and is specified in milliseconds.
// All axes to 80% over 500ms
await device.position(80, { duration: 500 });
// Per-axis control
await device.position([
{ index: 0, position: 100, duration: 300 },
{ index: 1, position: 20, duration: 600 },
]);The client selects HwPositionWithDuration when available, falling back to Position. Use device.canPosition to check support.
Stopping
Stop a single device or all devices at once:
// Stop everything on one device
await device.stop();
// Stop only outputs (keep sensor subscriptions)
await device.stop({ outputs: true });
// Stop all devices globally
await client.stopAll();device.stop() without options halts all features. Pass DeviceStopOptions to target a specific feature index or filter by inputs/outputs.
Devices report a messageTimingGap -- the minimum interval between commands. Sending commands faster than this interval may cause the server to drop messages. The client logs a warning when this happens but does not throttle automatically.