@blueyerobotics/blueye-ts 3.13.0 → 4.0.1
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/example.js +4 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -20
- package/dist/sonar-example.js +2 -4
- package/dist/src/async-queue.js +1 -5
- package/dist/src/binlog-parser.d.ts +2 -3
- package/dist/src/binlog-parser.js +33 -34
- package/dist/src/client.js +37 -79
- package/dist/src/schema.d.ts +1 -1
- package/dist/src/schema.js +10 -18
- package/package.json +16 -10
package/dist/example.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const index_1 = require("./index");
|
|
1
|
+
import { BlueyeClient } from "./index";
|
|
4
2
|
const main = async () => {
|
|
5
|
-
const client = new
|
|
3
|
+
const client = new BlueyeClient();
|
|
6
4
|
client.on("connected", async () => {
|
|
7
5
|
try {
|
|
8
6
|
// request battery information
|
|
@@ -12,8 +10,8 @@ const main = async () => {
|
|
|
12
10
|
const batteryTel = await client.getTelemetry("BatteryTel");
|
|
13
11
|
console.log("batteryTel:", batteryTel);
|
|
14
12
|
}
|
|
15
|
-
catch
|
|
16
|
-
//
|
|
13
|
+
catch {
|
|
14
|
+
// swallow request/telemetry errors and continue with the control demo
|
|
17
15
|
}
|
|
18
16
|
// send a control message to change the light intensity to 0.1
|
|
19
17
|
console.log("setting light intensity to 0.1 for 1 second...");
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("@blueyerobotics/protocol-definitions"), exports);
|
|
18
|
-
__exportStar(require("./src/binlog-parser"), exports);
|
|
19
|
-
__exportStar(require("./src/client"), exports);
|
|
20
|
-
__exportStar(require("./src/schema"), exports);
|
|
1
|
+
export { blueye, google } from "@blueyerobotics/protocol-definitions";
|
|
2
|
+
export * from "./src/binlog-parser";
|
|
3
|
+
export * from "./src/client";
|
|
4
|
+
export * from "./src/schema";
|
package/dist/sonar-example.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const index_1 = require("./index");
|
|
1
|
+
import { BlueyeClient } from "./index";
|
|
4
2
|
const main = async () => {
|
|
5
|
-
const client = new
|
|
3
|
+
const client = new BlueyeClient();
|
|
6
4
|
client.on("connected", () => {
|
|
7
5
|
console.log("client connected");
|
|
8
6
|
});
|
package/dist/src/async-queue.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AsyncQueue = void 0;
|
|
4
|
-
class AsyncQueue {
|
|
1
|
+
export class AsyncQueue {
|
|
5
2
|
lastPromise = Promise.resolve();
|
|
6
3
|
enqueue(fn) {
|
|
7
4
|
const run = this.lastPromise.then(() => fn());
|
|
@@ -9,4 +6,3 @@ class AsyncQueue {
|
|
|
9
6
|
return run;
|
|
10
7
|
}
|
|
11
8
|
}
|
|
12
|
-
exports.AsyncQueue = AsyncQueue;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Buffer } from "buffer";
|
|
2
1
|
import { type Protocol, type ProtocolKey, type ProtocolType } from "./client";
|
|
3
2
|
export type Message = {
|
|
4
3
|
[K in ProtocolKey]: {
|
|
@@ -20,9 +19,9 @@ export declare const parse: (rawData: Blob, fixTimes?: boolean) => Promise<Messa
|
|
|
20
19
|
/**
|
|
21
20
|
* Decompress the gzipped binlog data (.bez).
|
|
22
21
|
* @param rawData The compressed binary data to decompress (gzip format).
|
|
23
|
-
* @returns A promise that resolves to the decompressed data as a
|
|
22
|
+
* @returns A promise that resolves to the decompressed data as a Uint8Array.
|
|
24
23
|
*/
|
|
25
|
-
export declare const decompress: (rawData: Blob) => Promise<
|
|
24
|
+
export declare const decompress: (rawData: Blob) => Promise<Uint8Array<ArrayBuffer>>;
|
|
26
25
|
/**
|
|
27
26
|
* Parse the decompressed binlog data into structured messages.
|
|
28
27
|
* @param decompressed The gunzipped binlog data.
|
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const wire_1 = require("@bufbuild/protobuf/wire");
|
|
6
|
-
const buffer_1 = require("buffer");
|
|
7
|
-
const fflate_1 = require("fflate");
|
|
8
|
-
const client_1 = require("./client");
|
|
1
|
+
import { blueye } from "@blueyerobotics/protocol-definitions";
|
|
2
|
+
import { BinaryReader } from "@bufbuild/protobuf/wire";
|
|
3
|
+
import { Gunzip } from "fflate";
|
|
4
|
+
import { isInProtocol, } from "./client";
|
|
9
5
|
/**
|
|
10
6
|
* Parse a binlog file from raw (gzipped) data into structured messages..
|
|
11
7
|
* @param rawData The raw binary data of the binlog file (gzip format).
|
|
12
8
|
* @param fixTimes Fix the message times based on the last message's monotonic and unix timestamps. Useful for ensuring the times are in sync.
|
|
13
9
|
* @returns A promise that resolves to an array of parsed messages.
|
|
14
10
|
*/
|
|
15
|
-
const parse = async (rawData, fixTimes = true) => {
|
|
16
|
-
const decompressed = await
|
|
17
|
-
const messages =
|
|
11
|
+
export const parse = async (rawData, fixTimes = true) => {
|
|
12
|
+
const decompressed = await decompress(rawData);
|
|
13
|
+
const messages = parseMessages(decompressed, fixTimes);
|
|
18
14
|
return messages;
|
|
19
15
|
};
|
|
20
|
-
exports.parse = parse;
|
|
21
16
|
/**
|
|
22
17
|
* Decompress the gzipped binlog data (.bez).
|
|
23
18
|
* @param rawData The compressed binary data to decompress (gzip format).
|
|
24
|
-
* @returns A promise that resolves to the decompressed data as a
|
|
19
|
+
* @returns A promise that resolves to the decompressed data as a Uint8Array.
|
|
25
20
|
*/
|
|
26
|
-
const decompress = async (rawData) => {
|
|
27
|
-
const gunzip = new
|
|
21
|
+
export const decompress = async (rawData) => {
|
|
22
|
+
const gunzip = new Gunzip();
|
|
28
23
|
const blobReader = rawData.stream().getReader();
|
|
29
24
|
const chunks = [];
|
|
30
25
|
gunzip.ondata = (chunk) => {
|
|
@@ -43,17 +38,25 @@ const decompress = async (rawData) => {
|
|
|
43
38
|
}
|
|
44
39
|
gunzip.push(value);
|
|
45
40
|
}
|
|
46
|
-
|
|
41
|
+
let total = 0;
|
|
42
|
+
for (const c of chunks)
|
|
43
|
+
total += c.byteLength;
|
|
44
|
+
const out = new Uint8Array(total);
|
|
45
|
+
let offset = 0;
|
|
46
|
+
for (const c of chunks) {
|
|
47
|
+
out.set(c, offset);
|
|
48
|
+
offset += c.byteLength;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
47
51
|
};
|
|
48
|
-
exports.decompress = decompress;
|
|
49
52
|
/**
|
|
50
53
|
* Parse the decompressed binlog data into structured messages.
|
|
51
54
|
* @param decompressed The gunzipped binlog data.
|
|
52
55
|
* @param fixTimes Fix the message times based on the last message's monotonic and unix timestamps. Useful for ensuring the times are in sync.
|
|
53
56
|
* @returns An array of parsed messages with their timestamps, types, keys, and data.
|
|
54
57
|
*/
|
|
55
|
-
const parseMessages = (decompressed, fixTimes = true) => {
|
|
56
|
-
const reader = new
|
|
58
|
+
export const parseMessages = (decompressed, fixTimes = true) => {
|
|
59
|
+
const reader = new BinaryReader(decompressed);
|
|
57
60
|
let messages = [];
|
|
58
61
|
while (reader.pos < reader.len) {
|
|
59
62
|
const length = reader.uint32();
|
|
@@ -65,9 +68,9 @@ const parseMessages = (decompressed, fixTimes = true) => {
|
|
|
65
68
|
}
|
|
66
69
|
const msgBytes = decompressed.buffer.slice(start, end);
|
|
67
70
|
reader.pos = end;
|
|
68
|
-
const msg =
|
|
71
|
+
const msg = blueye.protocol.BinlogRecord.decode(new Uint8Array(msgBytes), length);
|
|
69
72
|
const key = msg.payload?.typeUrl.split(".").at(-1);
|
|
70
|
-
if (!key || !
|
|
73
|
+
if (!key || !isInProtocol(key)) {
|
|
71
74
|
console.warn(`Unknown protocol key: ${key}`);
|
|
72
75
|
continue;
|
|
73
76
|
}
|
|
@@ -75,17 +78,17 @@ const parseMessages = (decompressed, fixTimes = true) => {
|
|
|
75
78
|
console.warn(`Missing payload for key: ${key}`);
|
|
76
79
|
continue;
|
|
77
80
|
}
|
|
78
|
-
const data =
|
|
81
|
+
const data = blueye.protocol[key].decode(msg.payload.value);
|
|
79
82
|
let innerData;
|
|
80
83
|
if (key === "GetTelemetryRep") {
|
|
81
84
|
const telRep = data;
|
|
82
85
|
const innerKey = telRep.payload?.typeUrl.split(".").at(-1);
|
|
83
|
-
if (!innerKey || !
|
|
86
|
+
if (!innerKey || !isInProtocol(innerKey)) {
|
|
84
87
|
console.warn(`Unknown inner protocol key: ${innerKey}`);
|
|
85
88
|
continue;
|
|
86
89
|
}
|
|
87
90
|
innerData = telRep.payload
|
|
88
|
-
?
|
|
91
|
+
? blueye.protocol[innerKey].decode(telRep.payload.value)
|
|
89
92
|
: undefined;
|
|
90
93
|
}
|
|
91
94
|
let type = "Tel";
|
|
@@ -105,11 +108,10 @@ const parseMessages = (decompressed, fixTimes = true) => {
|
|
|
105
108
|
});
|
|
106
109
|
}
|
|
107
110
|
if (fixTimes) {
|
|
108
|
-
messages =
|
|
111
|
+
messages = fixMessageTimes(messages);
|
|
109
112
|
}
|
|
110
113
|
return messages;
|
|
111
114
|
};
|
|
112
|
-
exports.parseMessages = parseMessages;
|
|
113
115
|
/**
|
|
114
116
|
* Fix the message times based on the last message's monotonic and unix timestamps.
|
|
115
117
|
* @param messages The messages to fix the times for.
|
|
@@ -121,22 +123,20 @@ exports.parseMessages = parseMessages;
|
|
|
121
123
|
* @param bytes Raw bytes containing a single varint-length-prefixed BinlogRecord.
|
|
122
124
|
* @returns The parsed message, or null if the record is not a known protocol type.
|
|
123
125
|
*/
|
|
124
|
-
const parseFrame = (bytes) => {
|
|
125
|
-
const messages =
|
|
126
|
+
export const parseFrame = (bytes) => {
|
|
127
|
+
const messages = parseFrames(bytes);
|
|
126
128
|
return messages.length > 0 ? messages[0] : null;
|
|
127
129
|
};
|
|
128
|
-
exports.parseFrame = parseFrame;
|
|
129
130
|
/**
|
|
130
131
|
* Parse multiple contiguous varint-prefixed BinlogRecords from raw (uncompressed) bytes.
|
|
131
132
|
* Used for streaming playback where frame batches are fetched via HTTP Range requests.
|
|
132
133
|
* @param bytes Raw bytes containing one or more varint-length-prefixed BinlogRecords.
|
|
133
134
|
* @returns An array of parsed messages.
|
|
134
135
|
*/
|
|
135
|
-
const parseFrames = (bytes) => {
|
|
136
|
-
return
|
|
136
|
+
export const parseFrames = (bytes) => {
|
|
137
|
+
return parseMessages(bytes, false);
|
|
137
138
|
};
|
|
138
|
-
|
|
139
|
-
const fixMessageTimes = (messages) => {
|
|
139
|
+
export const fixMessageTimes = (messages) => {
|
|
140
140
|
if (messages.length === 0)
|
|
141
141
|
return messages;
|
|
142
142
|
const last = messages.at(-1);
|
|
@@ -150,4 +150,3 @@ const fixMessageTimes = (messages) => {
|
|
|
150
150
|
}
|
|
151
151
|
return messages;
|
|
152
152
|
};
|
|
153
|
-
exports.fixMessageTimes = fixMessageTimes;
|
package/dist/src/client.js
CHANGED
|
@@ -1,63 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.BlueyeClient = exports.isInProtocol = exports.MULTIBEAM_DEVICE_IDS = void 0;
|
|
37
|
-
const protocol_definitions_1 = require("@blueyerobotics/protocol-definitions");
|
|
38
|
-
const buffer_1 = require("buffer");
|
|
39
|
-
const consola_1 = require("consola");
|
|
40
|
-
const jszmq_1 = require("@blueyerobotics/jszmq");
|
|
41
|
-
const strict_event_emitter_1 = require("strict-event-emitter");
|
|
42
|
-
const async_queue_1 = require("./async-queue");
|
|
43
|
-
const schema_1 = require("./schema");
|
|
44
|
-
const semver = __importStar(require("semver"));
|
|
1
|
+
import { Pub as ZMQPub, Req as ZMQRep, Sub as ZMQSub, } from "@blueyerobotics/jszmq";
|
|
2
|
+
import { blueye } from "@blueyerobotics/protocol-definitions";
|
|
3
|
+
import { createConsola, LogLevels, } from "consola";
|
|
4
|
+
import * as semver from "semver";
|
|
5
|
+
import { Emitter } from "strict-event-emitter";
|
|
6
|
+
import { AsyncQueue } from "./async-queue";
|
|
7
|
+
import { responseSchema, telemetrySchema } from "./schema";
|
|
45
8
|
const DEFAULT_SUB_URL = "ws://192.168.1.101:9985";
|
|
46
9
|
const DEFAULT_RPC_URL = "ws://192.168.1.101:9986";
|
|
47
10
|
const DEFAULT_PUB_URL = "ws://192.168.1.101:9987";
|
|
48
11
|
const DEFAULT_SONAR_URL = "ws://192.168.1.101:9988";
|
|
49
|
-
|
|
50
|
-
const isInProtocol = (key) => {
|
|
51
|
-
return key in
|
|
12
|
+
export const MULTIBEAM_DEVICE_IDS = [13, 16, 18, 20, 29, 30, 41, 42];
|
|
13
|
+
export const isInProtocol = (key) => {
|
|
14
|
+
return key in blueye.protocol;
|
|
52
15
|
};
|
|
53
|
-
exports.isInProtocol = isInProtocol;
|
|
54
16
|
const hasSonarEndpoint = (version) => {
|
|
55
17
|
const coercedVersion = semver.coerce(version);
|
|
56
18
|
return coercedVersion
|
|
57
19
|
? semver.satisfies(coercedVersion, ">=4.7.0") || version.endsWith("-dev")
|
|
58
20
|
: false;
|
|
59
21
|
};
|
|
60
|
-
class BlueyeClient extends
|
|
22
|
+
export class BlueyeClient extends Emitter {
|
|
61
23
|
timeout;
|
|
62
24
|
reconnectInterval;
|
|
63
25
|
subUrl;
|
|
@@ -78,7 +40,7 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
78
40
|
pub: "disconnected",
|
|
79
41
|
sonar: "disconnected",
|
|
80
42
|
};
|
|
81
|
-
constructor({ subUrl = DEFAULT_SUB_URL, rpcUrl = DEFAULT_RPC_URL, pubUrl = DEFAULT_PUB_URL, sonarUrl = DEFAULT_SONAR_URL, timeout = 2000, reconnectInterval = 2000, logLevel =
|
|
43
|
+
constructor({ subUrl = DEFAULT_SUB_URL, rpcUrl = DEFAULT_RPC_URL, pubUrl = DEFAULT_PUB_URL, sonarUrl = DEFAULT_SONAR_URL, timeout = 2000, reconnectInterval = 2000, logLevel = LogLevels.info, autoConnect = false, } = {}) {
|
|
82
44
|
super();
|
|
83
45
|
this.timeout = timeout;
|
|
84
46
|
this.reconnectInterval = reconnectInterval;
|
|
@@ -86,12 +48,12 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
86
48
|
this.rpcUrl = rpcUrl;
|
|
87
49
|
this.pubUrl = pubUrl;
|
|
88
50
|
this.sonarUrl = sonarUrl;
|
|
89
|
-
this.sub = new
|
|
90
|
-
this.rpc = new
|
|
91
|
-
this.pub = new
|
|
92
|
-
this.sonarSub = new
|
|
93
|
-
this.queue = new
|
|
94
|
-
this.logger =
|
|
51
|
+
this.sub = new ZMQSub();
|
|
52
|
+
this.rpc = new ZMQRep();
|
|
53
|
+
this.pub = new ZMQPub();
|
|
54
|
+
this.sonarSub = new ZMQSub();
|
|
55
|
+
this.queue = new AsyncQueue();
|
|
56
|
+
this.logger = createConsola({
|
|
95
57
|
level: logLevel,
|
|
96
58
|
formatOptions: { colors: true, compact: false },
|
|
97
59
|
});
|
|
@@ -138,12 +100,12 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
138
100
|
}
|
|
139
101
|
}
|
|
140
102
|
handleTelemetryMessage(socketName, topic, msg) {
|
|
141
|
-
const { key, data } =
|
|
142
|
-
if (!
|
|
103
|
+
const { key, data } = responseSchema.parse({ key: topic, data: msg });
|
|
104
|
+
if (!isInProtocol(key) || !key.endsWith("Tel")) {
|
|
143
105
|
this.logger.warn(`[${socketName}] unknown protocol:`, key);
|
|
144
106
|
return;
|
|
145
107
|
}
|
|
146
|
-
const protocol =
|
|
108
|
+
const protocol = blueye.protocol[key];
|
|
147
109
|
const message = protocol.decode(data);
|
|
148
110
|
this.logger.verbose(`[${socketName}] message:`, key, message);
|
|
149
111
|
this.emit(key, message);
|
|
@@ -182,7 +144,7 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
182
144
|
...(msg.droneInfo?.gp?.gp2?.deviceList?.devices ?? []),
|
|
183
145
|
...(msg.droneInfo?.gp?.gp3?.deviceList?.devices ?? []),
|
|
184
146
|
].map((device) => device.deviceId);
|
|
185
|
-
if (devices.some((deviceId) =>
|
|
147
|
+
if (devices.some((deviceId) => MULTIBEAM_DEVICE_IDS.includes(deviceId))) {
|
|
186
148
|
this.logger.info("[sonar] multibeam device detected in DroneInfoTel");
|
|
187
149
|
this.isSonarDetected = true;
|
|
188
150
|
this.sonarSub.connect(this.sonarUrl);
|
|
@@ -222,10 +184,10 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
222
184
|
}
|
|
223
185
|
async sendRequest(req, opts = {}) {
|
|
224
186
|
this.ensureConnected("rpc");
|
|
225
|
-
if (!
|
|
187
|
+
if (!isInProtocol(req) || !req.endsWith("Req")) {
|
|
226
188
|
throw new Error(`[rpc] unknown protocol: ${req}`);
|
|
227
189
|
}
|
|
228
|
-
const protocol =
|
|
190
|
+
const protocol = blueye.protocol[req];
|
|
229
191
|
const message = protocol.create(opts);
|
|
230
192
|
const encoded = protocol.encode(message).finish();
|
|
231
193
|
const request = () => {
|
|
@@ -233,22 +195,22 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
233
195
|
const timer = setTimeout(() => reject(new Error("[rpc] request timed out")), this.timeout);
|
|
234
196
|
this.rpc.once("message", (topic, msg) => {
|
|
235
197
|
clearTimeout(timer);
|
|
236
|
-
resolve({
|
|
198
|
+
resolve({
|
|
199
|
+
key: new TextDecoder().decode(topic).split(".").at(-1) ?? "",
|
|
200
|
+
data: msg,
|
|
201
|
+
});
|
|
237
202
|
});
|
|
238
|
-
this.rpc.send([
|
|
239
|
-
buffer_1.Buffer.from(`blueye.protocol.${req}`),
|
|
240
|
-
buffer_1.Buffer.from(encoded),
|
|
241
|
-
]);
|
|
203
|
+
this.rpc.send([`blueye.protocol.${req}`, encoded]);
|
|
242
204
|
});
|
|
243
205
|
};
|
|
244
206
|
const { key, data } = await this.queue.enqueue(request);
|
|
245
207
|
if (key === "Empty") {
|
|
246
208
|
return null;
|
|
247
209
|
}
|
|
248
|
-
if (!
|
|
210
|
+
if (!isInProtocol(key) || !key.endsWith("Rep")) {
|
|
249
211
|
throw new Error(`[rpc] unknown response protocol: ${key}`);
|
|
250
212
|
}
|
|
251
|
-
const rep =
|
|
213
|
+
const rep = blueye.protocol[key];
|
|
252
214
|
const result = rep.decode(data);
|
|
253
215
|
this.logger.debug("[rpc] decoded:", result);
|
|
254
216
|
return result;
|
|
@@ -260,12 +222,12 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
260
222
|
if (!response) {
|
|
261
223
|
throw new Error(`[rpc] no response for telemetry request: ${type}`);
|
|
262
224
|
}
|
|
263
|
-
const { payload } =
|
|
225
|
+
const { payload } = telemetrySchema.parse(response);
|
|
264
226
|
const { typeUrl, value } = payload;
|
|
265
|
-
if (!
|
|
227
|
+
if (!isInProtocol(typeUrl) || !typeUrl.endsWith("Tel")) {
|
|
266
228
|
throw new Error(`[rpc] unknown telemetry typeUrl: ${typeUrl}`);
|
|
267
229
|
}
|
|
268
|
-
const result =
|
|
230
|
+
const result = blueye.protocol[typeUrl].decode(value);
|
|
269
231
|
this.logger.debug("[rpc] result:", result);
|
|
270
232
|
return result;
|
|
271
233
|
}
|
|
@@ -296,17 +258,13 @@ class BlueyeClient extends strict_event_emitter_1.Emitter {
|
|
|
296
258
|
}
|
|
297
259
|
async sendControl(ctrl, opts = {}) {
|
|
298
260
|
this.ensureConnected("pub");
|
|
299
|
-
if (!
|
|
261
|
+
if (!isInProtocol(ctrl) || !ctrl.endsWith("Ctrl")) {
|
|
300
262
|
throw new Error(`[pub] unknown protocol: ${ctrl}`);
|
|
301
263
|
}
|
|
302
|
-
const protocol =
|
|
264
|
+
const protocol = blueye.protocol[ctrl];
|
|
303
265
|
const message = protocol.create(opts);
|
|
304
266
|
const encoded = protocol.encode(message).finish();
|
|
305
267
|
this.logger.debug("[pub] sending control:", ctrl, message);
|
|
306
|
-
this.pub.send([
|
|
307
|
-
buffer_1.Buffer.from(`blueye.protocol.${ctrl}`),
|
|
308
|
-
buffer_1.Buffer.from(encoded),
|
|
309
|
-
]);
|
|
268
|
+
this.pub.send([`blueye.protocol.${ctrl}`, encoded]);
|
|
310
269
|
}
|
|
311
270
|
}
|
|
312
|
-
exports.BlueyeClient = BlueyeClient;
|
package/dist/src/schema.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export declare const responseSchema: z.ZodObject<{
|
|
|
6
6
|
export declare const telemetrySchema: z.ZodObject<{
|
|
7
7
|
payload: z.ZodObject<{
|
|
8
8
|
typeUrl: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
9
|
-
value: z.
|
|
9
|
+
value: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
|
|
10
10
|
}, z.core.$strip>;
|
|
11
11
|
}, z.core.$strip>;
|
package/dist/src/schema.js
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.telemetrySchema = exports.responseSchema = void 0;
|
|
7
|
-
const zod_1 = __importDefault(require("zod"));
|
|
8
|
-
exports.responseSchema = zod_1.default.object({
|
|
9
|
-
key: zod_1.default
|
|
1
|
+
import z from "zod";
|
|
2
|
+
const utf8 = new TextDecoder();
|
|
3
|
+
export const responseSchema = z.object({
|
|
4
|
+
key: z
|
|
10
5
|
.instanceof(Uint8Array)
|
|
11
|
-
.transform((val) =>
|
|
12
|
-
data:
|
|
6
|
+
.transform((val) => utf8.decode(val).split(".").at(-1) ?? ""),
|
|
7
|
+
data: z.instanceof(Uint8Array),
|
|
13
8
|
});
|
|
14
|
-
|
|
15
|
-
payload:
|
|
16
|
-
typeUrl:
|
|
17
|
-
value:
|
|
18
|
-
.any()
|
|
19
|
-
.refine((val) => val instanceof Buffer || val instanceof Uint8Array)
|
|
20
|
-
.transform((val) => (Buffer.isBuffer(val) ? val : Buffer.from(val))),
|
|
9
|
+
export const telemetrySchema = z.object({
|
|
10
|
+
payload: z.object({
|
|
11
|
+
typeUrl: z.string().transform((val) => val.split(".").at(-1) ?? ""),
|
|
12
|
+
value: z.instanceof(Uint8Array),
|
|
21
13
|
}),
|
|
22
14
|
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blueyerobotics/blueye-ts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "A TypeScript client for interacting with Blueye underwater drones.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/BluEye-Robotics/blueye-ts.git"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"type": "module",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./dist/index.js",
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
11
16
|
"files": [
|
|
12
17
|
"dist"
|
|
13
18
|
],
|
|
@@ -15,10 +20,9 @@
|
|
|
15
20
|
"author": "Blueye <contact@blueye.no> (https://blueye.no/)",
|
|
16
21
|
"license": "LGPL-3.0-only",
|
|
17
22
|
"dependencies": {
|
|
18
|
-
"@blueyerobotics/jszmq": "^0.
|
|
23
|
+
"@blueyerobotics/jszmq": "^0.3.0",
|
|
19
24
|
"@blueyerobotics/protocol-definitions": "3.2.0-a57cd215",
|
|
20
25
|
"@bufbuild/protobuf": "^2.11.0",
|
|
21
|
-
"buffer": "^6.0.3",
|
|
22
26
|
"consola": "^3.4.2",
|
|
23
27
|
"fflate": "^0.8.2",
|
|
24
28
|
"semver": "^7.7.4",
|
|
@@ -29,13 +33,15 @@
|
|
|
29
33
|
"@biomejs/biome": "2.3.14",
|
|
30
34
|
"@types/node": "^25.4.0",
|
|
31
35
|
"@types/semver": "^7.7.1",
|
|
32
|
-
"
|
|
36
|
+
"tsx": "^4.20.7",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^4.0.5"
|
|
33
39
|
},
|
|
34
40
|
"scripts": {
|
|
35
|
-
"start": "
|
|
36
|
-
"start:sonar": "
|
|
41
|
+
"start": "tsx example.ts",
|
|
42
|
+
"start:sonar": "tsx sonar-example.ts",
|
|
37
43
|
"build": "tsc",
|
|
38
|
-
"
|
|
39
|
-
"test
|
|
44
|
+
"check": "biome ci",
|
|
45
|
+
"test": "vitest run"
|
|
40
46
|
}
|
|
41
47
|
}
|