@blueyerobotics/blueye-ts 3.11.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/client.d.ts +1 -0
- package/dist/src/client.js +55 -21
- package/package.json +3 -3
package/dist/src/client.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ export declare class BlueyeClient extends Emitter<Events> {
|
|
|
60
60
|
disconnect(): void;
|
|
61
61
|
sendRequest<T extends Req>(req: T, opts?: CreateArgs<T>): Promise<DecodedOutput<T> | null>;
|
|
62
62
|
getTelemetry<T extends Tel>(type: T): Promise<DecodedTelOutput<T>>;
|
|
63
|
+
waitForTelemetry<T extends Tel>(type: T, timeout?: number | null): Promise<DecodedTelOutput<T>>;
|
|
63
64
|
sendControl<T extends Ctrl>(ctrl: T, opts?: CreateArgs<T>): Promise<void>;
|
|
64
65
|
}
|
|
65
66
|
export {};
|
package/dist/src/client.js
CHANGED
|
@@ -105,23 +105,8 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
105
105
|
this.sonarSub.on("message", (topic, msg) => {
|
|
106
106
|
this.handleTelemetryMessage("sonar", topic, msg);
|
|
107
107
|
});
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
if (!hasSonarEndpoint(version ?? "")) {
|
|
111
|
-
this.logger.warn(`[sonar] incompatible Blunux version detected in DroneInfoTel: ${version}; sonar telemetry may not be available`);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const devices = [
|
|
115
|
-
...(msg.droneInfo?.gp?.gp1?.deviceList?.devices ?? []),
|
|
116
|
-
...(msg.droneInfo?.gp?.gp2?.deviceList?.devices ?? []),
|
|
117
|
-
...(msg.droneInfo?.gp?.gp3?.deviceList?.devices ?? []),
|
|
118
|
-
].map((device) => device.deviceId);
|
|
119
|
-
if (devices.some((deviceId) => exports.MULTIBEAM_DEVICE_IDS.includes(deviceId))) {
|
|
120
|
-
this.logger.info("[sonar] multibeam device detected in DroneInfoTel:", devices);
|
|
121
|
-
this.isSonarDetected = true;
|
|
122
|
-
this.sonarSub.connect(this.sonarUrl);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
108
|
+
this.emit(this.state);
|
|
109
|
+
this.logger.info(`[client] ${this.state}`);
|
|
125
110
|
if (autoConnect) {
|
|
126
111
|
this.connect();
|
|
127
112
|
}
|
|
@@ -142,11 +127,15 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
142
127
|
if (this.socketState[name] === newState) {
|
|
143
128
|
return;
|
|
144
129
|
}
|
|
130
|
+
const oldState = this.state;
|
|
145
131
|
this.socketState[name] = newState;
|
|
146
132
|
this.logger.info(`[${name}] ${newState}`);
|
|
147
133
|
this.emit(`${name}-${newState}`);
|
|
148
134
|
// If all sockets are connected, emit "connected"
|
|
149
135
|
this.emit(this.state);
|
|
136
|
+
if (oldState !== this.state) {
|
|
137
|
+
this.logger.info(`[client] ${this.state}`);
|
|
138
|
+
}
|
|
150
139
|
}
|
|
151
140
|
handleTelemetryMessage(socketName, topic, msg) {
|
|
152
141
|
const { key, data } = schema_1.responseSchema.parse({ key: topic, data: msg });
|
|
@@ -172,7 +161,7 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
172
161
|
});
|
|
173
162
|
}
|
|
174
163
|
ensureConnected(operation) {
|
|
175
|
-
if (this.
|
|
164
|
+
if (this.socketState[operation] !== "connected") {
|
|
176
165
|
throw new Error(`[client] cannot send ${operation} while ${this.state}; call connect() and wait for "connected"`);
|
|
177
166
|
}
|
|
178
167
|
}
|
|
@@ -181,14 +170,34 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
181
170
|
this.logger.warn("[client] already connecting or connected");
|
|
182
171
|
return;
|
|
183
172
|
}
|
|
173
|
+
this.once("connected", async () => {
|
|
174
|
+
const msg = await this.waitForTelemetry("DroneInfoTel");
|
|
175
|
+
const version = msg.droneInfo?.blunuxVersion;
|
|
176
|
+
if (!hasSonarEndpoint(version ?? "")) {
|
|
177
|
+
this.logger.warn(`[sonar] incompatible Blunux version detected in DroneInfoTel: ${version}; sonar telemetry may not be available`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const devices = [
|
|
181
|
+
...(msg.droneInfo?.gp?.gp1?.deviceList?.devices ?? []),
|
|
182
|
+
...(msg.droneInfo?.gp?.gp2?.deviceList?.devices ?? []),
|
|
183
|
+
...(msg.droneInfo?.gp?.gp3?.deviceList?.devices ?? []),
|
|
184
|
+
].map((device) => device.deviceId);
|
|
185
|
+
if (devices.some((deviceId) => exports.MULTIBEAM_DEVICE_IDS.includes(deviceId))) {
|
|
186
|
+
this.logger.info("[sonar] multibeam device detected in DroneInfoTel");
|
|
187
|
+
this.isSonarDetected = true;
|
|
188
|
+
this.sonarSub.connect(this.sonarUrl);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
184
191
|
this.sub.options.reconnectInterval = this.reconnectInterval;
|
|
185
192
|
this.rpc.options.reconnectInterval = this.reconnectInterval;
|
|
186
193
|
this.pub.options.reconnectInterval = this.reconnectInterval;
|
|
187
194
|
this.sonarSub.options.reconnectInterval = this.reconnectInterval;
|
|
188
195
|
this.shouldBeConnected = true;
|
|
189
|
-
for (const name of ["sub", "rpc", "pub"
|
|
196
|
+
for (const name of ["sub", "rpc", "pub"]) {
|
|
190
197
|
this.updateSocketState(name, "connecting");
|
|
191
198
|
}
|
|
199
|
+
this.logger.info(`[client] ${this.state}`);
|
|
200
|
+
this.emit(this.state);
|
|
192
201
|
this.sub.subscribe("");
|
|
193
202
|
this.sub.connect(this.subUrl);
|
|
194
203
|
this.rpc.connect(this.rpcUrl);
|
|
@@ -212,7 +221,7 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
223
|
async sendRequest(req, opts = {}) {
|
|
215
|
-
this.ensureConnected("
|
|
224
|
+
this.ensureConnected("rpc");
|
|
216
225
|
if (!(0, exports.isInProtocol)(req) || !req.endsWith("Req")) {
|
|
217
226
|
throw new Error(`[rpc] unknown protocol: ${req}`);
|
|
218
227
|
}
|
|
@@ -260,8 +269,33 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
260
269
|
this.logger.debug("[rpc] result:", result);
|
|
261
270
|
return result;
|
|
262
271
|
}
|
|
272
|
+
async waitForTelemetry(type, timeout = null) {
|
|
273
|
+
// Tries to get the latest telemetry via RPC first, in case we already have it cached in Blunux
|
|
274
|
+
try {
|
|
275
|
+
return await this.getTelemetry(type);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
this.logger.trace(`[client] failed to get latest ${type} via RPC:`, error);
|
|
279
|
+
}
|
|
280
|
+
// If that fails, wait for the next telemetry message to arrive via SUB
|
|
281
|
+
return new Promise((resolve, reject) => {
|
|
282
|
+
const listener = (...data) => {
|
|
283
|
+
this.off(type, listener);
|
|
284
|
+
if (timer)
|
|
285
|
+
clearTimeout(timer);
|
|
286
|
+
resolve(data[0]);
|
|
287
|
+
};
|
|
288
|
+
const timer = timeout
|
|
289
|
+
? setTimeout(() => {
|
|
290
|
+
this.off(type, listener);
|
|
291
|
+
reject(new Error(`[client] timed out waiting for ${type} telemetry`));
|
|
292
|
+
}, timeout)
|
|
293
|
+
: null;
|
|
294
|
+
this.on(type, listener);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
263
297
|
async sendControl(ctrl, opts = {}) {
|
|
264
|
-
this.ensureConnected("
|
|
298
|
+
this.ensureConnected("pub");
|
|
265
299
|
if (!(0, exports.isInProtocol)(ctrl) || !ctrl.endsWith("Ctrl")) {
|
|
266
300
|
throw new Error(`[pub] unknown protocol: ${ctrl}`);
|
|
267
301
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blueyerobotics/blueye-ts",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "A TypeScript client for interacting with Blueye underwater drones.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"license": "LGPL-3.0-only",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@blueyerobotics/jszmq": "^0.2.0",
|
|
19
|
-
"@blueyerobotics/protocol-definitions": "3.2.0-
|
|
19
|
+
"@blueyerobotics/protocol-definitions": "3.2.0-a57cd215",
|
|
20
20
|
"@bufbuild/protobuf": "^2.11.0",
|
|
21
21
|
"buffer": "^6.0.3",
|
|
22
22
|
"consola": "^3.4.2",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"start": "pnpm build && node dist/example.js",
|
|
36
36
|
"start:sonar": "pnpm build && node dist/sonar-example.js",
|
|
37
37
|
"build": "tsc",
|
|
38
|
-
"test": "pnpm build && node --test --test-concurrency=1 test/**/*.test.js",
|
|
38
|
+
"test": "pnpm build && node --test --experimental-test-isolation=none --test-concurrency=1 test/**/*.test.js",
|
|
39
39
|
"test:one": "node --test --test-concurrency=1"
|
|
40
40
|
}
|
|
41
41
|
}
|