@blueyerobotics/blueye-ts
v5.0.18
Published
A TypeScript client for interacting with Blueye underwater drones.
Readme
blueye-ts
A TypeScript package for interacting with Blueye underwater drones and parsing binlog files.
Installation
npm install @blueyerobotics/blueye-tsUsage
import { BlueyeClient } from "@blueyerobotics/blueye-ts";
const client = new BlueyeClient();
client.on("connected", async () => {
// request battery information
const batteryRep = await client.sendRequest("GetBatteryReq");
console.log("batteryRep:", batteryRep);
// get latest battery telemetry
const batteryTel = await client.getTelemetry("BatteryTel");
console.log("batteryTel:", batteryTel);
// send a control message to change the light intensity to 1
await client.sendControl("LightsCtrl", { lights: { value: 1 } });
});
// subscribe to battery telemetry updates
client.on("BatteryTel", data => {
console.log("received BatteryTel:", data);
});
client.connect();Connection states
BlueyeClient manages four sockets: sub, rpc, pub, and sonar. Global state events (connecting, connected, disconnected) are emitted when the derived state changes. Per-socket events use the ${socket}-${state} format (e.g. sonar-connected, rpc-connecting):
client.on("connected", () => {
console.log("all required sockets ready");
});
client.on("sonar-connected", () => {
console.log("sonar socket ready");
});The derived client.state reflects the aggregate of the core sockets (sub, rpc, pub). If a multibeam sonar is detected via DroneInfoTel, the sonar socket is also required for connected.
disconnected:connect()has not been called.connecting: one or more required sockets are not yet ready.connected: all required sockets are ready — safe to callsendRequest(),getTelemetry(), andsendControl().
All state events — global and per-socket — are edge-triggered: they fire exactly once per actual change. If the client loses one or more sockets after being connected, the derived state moves back to connecting (with a connecting event). sendRequest() and sendControl() reject unless the client is in the connected state.
Telemetry staleness watchdog
A dead link does not always produce a close event — a tether or radio drop can leave the sockets looking connected while telemetry silently freezes, until TCP retransmission gives up minutes later. Because the drone publishes telemetry continuously (e.g. DroneTimeTel at 1 Hz), the client watches for it: if no message arrives on the telemetry socket for stalenessTimeout milliseconds (default 5000) while connected, the client force-drops its connections. This converts the silent failure into the normal loss path — consumers see the usual connecting event, and the built-in reconnect loop restores the session when the link returns.
The watchdog only arms after the first telemetry message of a connection (a connection that never produced telemetry is not judged stale), watches the main telemetry socket only (sonar can be legitimately quiet), and disarms on disconnect(). Set stalenessTimeout: 0 to disable it:
const client = new BlueyeClient({ stalenessTimeout: 0 }); // no watchdogTransports
BlueyeClient talks to its sockets through a small transport interface. The default adapter uses jszmq over WebSockets; an in-memory adapter ships alongside it for tests, so application code using BlueyeClient can be exercised without a drone or any network:
import { BlueyeClient, InMemoryTransport } from "@blueyerobotics/blueye-ts";
const transport = new InMemoryTransport();
const rpc = transport.listen("mem://rpc");
rpc.onMessage(([topic, payload], reply) => {
// inspect the request, reply([topic, encoded]) as the drone would
});
transport.listen("mem://sub");
transport.listen("mem://pub");
transport.listen("mem://sonar");
const client = new BlueyeClient({
subUrl: "mem://sub",
rpcUrl: "mem://rpc",
pubUrl: "mem://pub",
sonarUrl: "mem://sonar",
transport,
});When you are done with a client, call client.close() to release the underlying sockets permanently; a closed client cannot be reused.
Sonar support
BlueyeClient connects the sonar websocket endpoint at ws://192.168.1.101:9988 when a supported multibeam device is detected in a DroneInfoTel message.
- On
connect(), the sonar socket subscribes but only connects when a known multibeam device ID is found in the guest-port device list. Detection inspects everyDroneInfoTel— one is requested over RPC when the connection comes up, and any laterDroneInfoTelarriving over SUB is also considered. - Once detected, the sonar socket connects and the global
connectedstate requires it to be ready. Detection resets ondisconnect(); the next connection starts without requiring sonar until it is detected again. - Sonar telemetry such as
MultibeamPingTel,MultibeamConfigTel, andMultibeamDiscoveryTelis emitted through the same typed event interface as other telemetry messages.
