nep-cli 0.1.8 → 0.2.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/bin/index.js +149 -993
- package/package.json +3 -3
package/bin/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { program } = require('commander');
|
|
4
|
+
const { version } = require('../package.json');
|
|
4
5
|
const os = require('os');
|
|
5
6
|
const zmq = require("zeromq");
|
|
6
7
|
var nep = require('nep-js');
|
|
7
|
-
var nep_configuration = { current_port:
|
|
8
|
+
var nep_configuration = { current_port: 50200, IP: "0.0.0.0", brokers: {} }
|
|
8
9
|
const { exec } = require('child_process');
|
|
9
10
|
const { AutoComplete } = require('enquirer');
|
|
10
11
|
|
|
@@ -16,6 +17,52 @@ const socketIo = require('socket.io');
|
|
|
16
17
|
const fs = require('fs');
|
|
17
18
|
const zmqc = require("zeromq/v5-compat");
|
|
18
19
|
|
|
20
|
+
const PORT_MASTER_INFO = 50001; // Default port for master info
|
|
21
|
+
const PORT_IMAGES = [];
|
|
22
|
+
for (let i = 50050; i <= 50060; i++) {
|
|
23
|
+
PORT_IMAGES.push(i);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
program
|
|
28
|
+
.version(version)
|
|
29
|
+
.description('NEP-CLI')
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('ip')
|
|
33
|
+
.description('Display current Wi-Fi and Ethernet IP addresses of this computer')
|
|
34
|
+
.action(() => {
|
|
35
|
+
try {
|
|
36
|
+
// subsitude by interfaces = nep.getNetworkInterfaces --> {"wifi":wifiInterfaces, "eth":ethernetInterface}
|
|
37
|
+
const platform = os.platform();
|
|
38
|
+
let wifiInterfaces, ethernetInterface;
|
|
39
|
+
|
|
40
|
+
if (platform === 'linux') {
|
|
41
|
+
wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(wlan|wlp|wl|en)\d*$/i.test(ifname));
|
|
42
|
+
ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^(eth|enp|eno)\d*$/i.test(ifname));
|
|
43
|
+
} else if (platform === 'win32') {
|
|
44
|
+
wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(Wireless|Wi-Fi)/i.test(ifname));
|
|
45
|
+
ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^Ethernet/i.test(ifname));
|
|
46
|
+
} else if (platform === 'darwin') {
|
|
47
|
+
wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^en\d*$/i.test(ifname));
|
|
48
|
+
ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^en\d*$/i.test(ifname));
|
|
49
|
+
} else {
|
|
50
|
+
console.log('Unsupported operating system.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
wifiInterfaces.forEach(wifiInterface => {
|
|
55
|
+
const ipAddress = nep.getIPAddress(wifiInterface);
|
|
56
|
+
nep.printIPAddress(`Wi-Fi (${wifiInterface})`, ipAddress);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
nep.printIPAddress('Ethernet', nep.getIPAddress(ethernetInterface));
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error('An error occurred:', error.message);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
|
|
19
66
|
|
|
20
67
|
// Node saved here
|
|
21
68
|
var nodes_register = {};
|
|
@@ -24,7 +71,7 @@ var nodes_register = {};
|
|
|
24
71
|
var topic_register = {};
|
|
25
72
|
|
|
26
73
|
class MasterLocal {
|
|
27
|
-
constructor(IP = '
|
|
74
|
+
constructor(IP = '0.0.0.0', port_ = 50000) {
|
|
28
75
|
this.port = String(port_)
|
|
29
76
|
var address = "tcp://" + IP + ":" + this.port
|
|
30
77
|
console.log("New Master in: " + address)
|
|
@@ -136,7 +183,6 @@ var onNewTopic = function (node_request, topic_register) {
|
|
|
136
183
|
}
|
|
137
184
|
|
|
138
185
|
|
|
139
|
-
|
|
140
186
|
var createBroker = function (topic) {
|
|
141
187
|
try {
|
|
142
188
|
var broker = new Broker(nep_configuration["IP"], nep_configuration["current_port"] + 1, nep_configuration["current_port"])
|
|
@@ -206,97 +252,47 @@ var restartTopics = function (node_request) {
|
|
|
206
252
|
onUpdateTopicList(topic_register)
|
|
207
253
|
}
|
|
208
254
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
console.log(
|
|
255
|
+
const processMsg = (json_msg, nodes_register, topic_register) => {
|
|
256
|
+
const node_request = JSON.parse(json_msg);
|
|
257
|
+
const { node, socket, topic, pid } = node_request;
|
|
258
|
+
console.log(`NEP: Node request - node: ${node}, socket: ${socket}, topic: ${topic}`);
|
|
213
259
|
|
|
214
260
|
// Check node status
|
|
215
|
-
if (
|
|
216
|
-
|
|
261
|
+
if (node) {
|
|
217
262
|
// Kill previous node with the same name
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
console.log("Kill node: " + node_request['node'])
|
|
228
|
-
nep.killNode(current_pid)
|
|
263
|
+
if (node in nodes_register) {
|
|
264
|
+
console.log(`--- Node *${node}* already defined ---`);
|
|
265
|
+
const current_pid = nodes_register[node];
|
|
266
|
+
if (pid !== current_pid) {
|
|
267
|
+
if (!node.startsWith('nep-cli')) {
|
|
268
|
+
// TODO: Reset topics in node for graph
|
|
269
|
+
console.log(`Kill node: ${node}`);
|
|
270
|
+
nep.killNode(current_pid);
|
|
271
|
+
}
|
|
229
272
|
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
console.log("--- New Node *" + node_request['node'] + "* ---")
|
|
273
|
+
} else {
|
|
274
|
+
console.log(`--- New Node *${node}* ---`);
|
|
233
275
|
}
|
|
234
276
|
}
|
|
235
277
|
|
|
236
278
|
// Update node info
|
|
237
|
-
nodes_register[
|
|
238
|
-
|
|
239
|
-
var topic = String(node_request['topic'])
|
|
279
|
+
nodes_register[node] = pid;
|
|
280
|
+
|
|
240
281
|
// Check topic status
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
282
|
+
const topicStr = String(topic);
|
|
283
|
+
if (topicStr in topic_register) {
|
|
284
|
+
console.log(`--- Topic *${topicStr}* already registered ---`);
|
|
244
285
|
// Send information of topic already defined
|
|
245
|
-
|
|
246
|
-
return JSON.stringify(response)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
console.log(" --- New topic : *" + topic + "* ---")
|
|
286
|
+
const response = onRegisteredTopic(node_request, topic_register, topicStr);
|
|
287
|
+
return JSON.stringify(response);
|
|
288
|
+
} else {
|
|
289
|
+
console.log(`--- New topic: *${topicStr}* ---`);
|
|
250
290
|
// Create new broker
|
|
251
|
-
|
|
252
|
-
return JSON.stringify(response)
|
|
291
|
+
const response = onNewTopic(node_request, topic_register);
|
|
292
|
+
return JSON.stringify(response);
|
|
253
293
|
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const PORT_MASTER_INFO = 7010; // Default port for master info
|
|
257
|
-
const PORT_IMAGE = 3000;
|
|
258
|
-
const PORT_IMAGES = [];
|
|
259
|
-
for (let i = 3020; i <= 3040; i++) {
|
|
260
|
-
PORT_IMAGES.push(i);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
program
|
|
265
|
-
.version('"0.1.2')
|
|
266
|
-
.description('NEP+ CLI');
|
|
267
|
-
|
|
268
|
-
program
|
|
269
|
-
.command('ip')
|
|
270
|
-
.description('Display current Wi-Fi and Ethernet IP addresses of this computer')
|
|
271
|
-
.action(() => {
|
|
272
|
-
const interfaces = os.networkInterfaces();
|
|
273
|
-
|
|
274
|
-
// Find Wi-Fi interface
|
|
275
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
276
|
-
if (wifiInterface) {
|
|
277
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
278
|
-
if (wifiIPv4) {
|
|
279
|
-
console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
|
|
280
|
-
} else {
|
|
281
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
282
|
-
}
|
|
283
|
-
} else {
|
|
284
|
-
console.log('Wi-Fi interface not found.');
|
|
285
|
-
}
|
|
294
|
+
};
|
|
286
295
|
|
|
287
|
-
// Find Ethernet interface
|
|
288
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
289
|
-
if (ethernetInterface) {
|
|
290
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
291
|
-
if (ethernetIPv4) {
|
|
292
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
293
|
-
} else {
|
|
294
|
-
console.log('No Ethernet IPv4 address found.');
|
|
295
|
-
}
|
|
296
|
-
} else {
|
|
297
|
-
console.log('Ethernet interface not found.');
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
296
|
|
|
301
297
|
program
|
|
302
298
|
.command('app')
|
|
@@ -365,7 +361,6 @@ program
|
|
|
365
361
|
});
|
|
366
362
|
|
|
367
363
|
|
|
368
|
-
|
|
369
364
|
program
|
|
370
365
|
.command('master')
|
|
371
366
|
.description('Start NEP master in localhost')
|
|
@@ -374,7 +369,7 @@ program
|
|
|
374
369
|
var node = new nep.Node("nep-cli");
|
|
375
370
|
console.log("Starting NEP master in terminal")
|
|
376
371
|
var master = new MasterLocal();
|
|
377
|
-
var info = new nep.MasterInfoServer(IP = '
|
|
372
|
+
var info = new nep.MasterInfoServer(IP = '0.0.0.0', topics = topic_register, port_=PORT_MASTER_INFO);
|
|
378
373
|
} catch (error) {
|
|
379
374
|
if (error.message.includes('EADDRINUSE')) {
|
|
380
375
|
console.error("Error: Address already in use. Another instance of NEP master might be running.");
|
|
@@ -384,78 +379,6 @@ program
|
|
|
384
379
|
}
|
|
385
380
|
});
|
|
386
381
|
|
|
387
|
-
program
|
|
388
|
-
.command('master-wifi')
|
|
389
|
-
.description('Start NEP master in Wi-Fi network')
|
|
390
|
-
.action(async () => {
|
|
391
|
-
|
|
392
|
-
const interfaces = os.networkInterfaces();
|
|
393
|
-
|
|
394
|
-
// Find Wi-Fi interface
|
|
395
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
396
|
-
if (wifiInterface) {
|
|
397
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
398
|
-
if (wifiIPv4) {
|
|
399
|
-
console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
|
|
400
|
-
try {
|
|
401
|
-
var node = new nep.Node("nep-cli");
|
|
402
|
-
nep_configuration["IP"] = wifiIPv4.address;
|
|
403
|
-
var master = new MasterLocal(IP = wifiIPv4.address);
|
|
404
|
-
var info = new nep.MasterInfoServer(IP = wifiIPv4.address, topics = topic_register);
|
|
405
|
-
} catch (error) {
|
|
406
|
-
if (error.message.includes('EADDRINUSE')) {
|
|
407
|
-
console.error("Error: Address already in use. Another instance of NEP master might be running.");
|
|
408
|
-
} else {
|
|
409
|
-
console.error("An error occurred:", error.message);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
} else {
|
|
414
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
console.log('Wi-Fi interface not found.');
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
program
|
|
421
|
-
.command('master-eth')
|
|
422
|
-
.description('Start NEP master in Ethernet network')
|
|
423
|
-
.action(async () => {
|
|
424
|
-
|
|
425
|
-
const interfaces = os.networkInterfaces();
|
|
426
|
-
|
|
427
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
428
|
-
if (ethernetInterface) {
|
|
429
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
430
|
-
if (ethernetIPv4) {
|
|
431
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
432
|
-
var node = new nep.Node("nep-cli");
|
|
433
|
-
nep_configuration["IP"] = ethernetIPv4.address;
|
|
434
|
-
var master = new MasterLocal(IP = ethernetIPv4.address);
|
|
435
|
-
var info = new nep.MasterInfoServer(IP = ethernetIPv4.address, topics = topic_register);
|
|
436
|
-
} else {
|
|
437
|
-
console.log('No Ethernet IPv4 address found.');
|
|
438
|
-
}
|
|
439
|
-
} else {
|
|
440
|
-
console.log('Ethernet interface not found.');
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
program
|
|
446
|
-
.command('master-ip <ip>')
|
|
447
|
-
.description('Start NEP master in some specific IP')
|
|
448
|
-
.action(async (ip) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
console.log(`IP Address: ${ip}`);
|
|
452
|
-
var node = new nep.Node("nep-cli");
|
|
453
|
-
nep_configuration["IP"] = ip;
|
|
454
|
-
var master = new MasterLocal(IP = ip);
|
|
455
|
-
var info = new nep.MasterInfoServer(IP = ip, topics = topic_register);
|
|
456
|
-
|
|
457
|
-
});
|
|
458
|
-
|
|
459
382
|
|
|
460
383
|
program
|
|
461
384
|
.command('topics')
|
|
@@ -510,93 +433,6 @@ program
|
|
|
510
433
|
await getTopics(); // Call the function to get topics
|
|
511
434
|
});
|
|
512
435
|
|
|
513
|
-
program
|
|
514
|
-
.command('topics-eth')
|
|
515
|
-
.description('Get list of NEP+ topics over Ethernet')
|
|
516
|
-
.action(async () => {
|
|
517
|
-
const interfaces = os.networkInterfaces();
|
|
518
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
519
|
-
|
|
520
|
-
if (ethernetInterface) {
|
|
521
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
522
|
-
if (ethernetIPv4) {
|
|
523
|
-
const master_ip = ethernetIPv4.address;
|
|
524
|
-
console.log('Asking to NEP+ master in -', ethernetIPv4.address);
|
|
525
|
-
console.log("\n")
|
|
526
|
-
await getAndDisplayTopics(master_ip);
|
|
527
|
-
} else {
|
|
528
|
-
console.log('No Ethernet IPv4 address found.');
|
|
529
|
-
}
|
|
530
|
-
} else {
|
|
531
|
-
console.log('Ethernet interface not found.');
|
|
532
|
-
}
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
program
|
|
537
|
-
.command('topics-wifi')
|
|
538
|
-
.description('Get list of NEP+ topics over Wi-Fi')
|
|
539
|
-
.action(async () => {
|
|
540
|
-
const interfaces = os.networkInterfaces();
|
|
541
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
542
|
-
|
|
543
|
-
if (wifiInterface) {
|
|
544
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
545
|
-
if (wifiIPv4) {
|
|
546
|
-
const master_ip = wifiIPv4.address; // Set the Wi-Fi IP address dynamically
|
|
547
|
-
console.log('Asking to NEP+ master in -', wifiIPv4.address);
|
|
548
|
-
console.log("\n")
|
|
549
|
-
const TIMEOUT_DURATION = 5000;
|
|
550
|
-
|
|
551
|
-
async function getTopics() {
|
|
552
|
-
var requester = new zmq.Request();
|
|
553
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
554
|
-
|
|
555
|
-
let msg = { "input": "topics" };
|
|
556
|
-
var message = JSON.stringify(msg);
|
|
557
|
-
|
|
558
|
-
try {
|
|
559
|
-
const responsePromise = new Promise(async (resolve, reject) => {
|
|
560
|
-
await requester.send(message);
|
|
561
|
-
const [result] = await requester.receive();
|
|
562
|
-
var results = JSON.parse(result.toString());
|
|
563
|
-
resolve(results);
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
const timeoutPromise = new Promise((resolve, reject) => {
|
|
567
|
-
setTimeout(() => {
|
|
568
|
-
reject(new Error("Timed out, NEP master over Wi-Fi was not found"));
|
|
569
|
-
}, TIMEOUT_DURATION);
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
const results = await Promise.race([responsePromise, timeoutPromise]);
|
|
573
|
-
|
|
574
|
-
if (results["state"] === "success") {
|
|
575
|
-
availableTopics = results["input"]; // Store the topics here
|
|
576
|
-
console.log("");
|
|
577
|
-
results["input"].forEach(element => {
|
|
578
|
-
console.log(element);
|
|
579
|
-
});
|
|
580
|
-
} else {
|
|
581
|
-
console.log("No topics yet");
|
|
582
|
-
}
|
|
583
|
-
} catch (error) {
|
|
584
|
-
console.error("Error:", error.message);
|
|
585
|
-
} finally {
|
|
586
|
-
process.exit();
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
await getTopics();
|
|
591
|
-
|
|
592
|
-
} else {
|
|
593
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
594
|
-
}
|
|
595
|
-
} else {
|
|
596
|
-
console.log('Wi-Fi interface not found.');
|
|
597
|
-
}
|
|
598
|
-
});
|
|
599
|
-
|
|
600
436
|
|
|
601
437
|
program
|
|
602
438
|
.command('listen <topic>')
|
|
@@ -648,9 +484,10 @@ program
|
|
|
648
484
|
run();
|
|
649
485
|
});
|
|
650
486
|
|
|
487
|
+
|
|
651
488
|
program
|
|
652
|
-
.command('
|
|
653
|
-
.description('Subscribe to a NEP+ topic
|
|
489
|
+
.command('echo <topic>')
|
|
490
|
+
.description('Subscribe to a NEP+ topic and display raw string messages')
|
|
654
491
|
.action(async (topic) => {
|
|
655
492
|
const interfaces = os.networkInterfaces();
|
|
656
493
|
|
|
@@ -669,10 +506,11 @@ program
|
|
|
669
506
|
|
|
670
507
|
var node = new nep.Node("nep-cli-sub");
|
|
671
508
|
var conf = node.hybrid(master_ip);
|
|
672
|
-
sub = node.new_sub(topic, "
|
|
509
|
+
sub = node.new_sub(topic, "string", callback, conf);
|
|
673
510
|
};
|
|
674
511
|
|
|
675
|
-
|
|
512
|
+
var master_ip = "127.0.0.1";
|
|
513
|
+
async function run() {
|
|
676
514
|
var requester = new zmq.Request();
|
|
677
515
|
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
678
516
|
|
|
@@ -694,461 +532,97 @@ program
|
|
|
694
532
|
}
|
|
695
533
|
}
|
|
696
534
|
|
|
697
|
-
|
|
698
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
699
|
-
if (ethernetInterface) {
|
|
700
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
701
|
-
if (ethernetIPv4) {
|
|
702
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
703
|
-
run(ethernetIPv4.address)
|
|
704
|
-
} else {
|
|
705
|
-
console.log('No Ethernet IPv4 address found.');
|
|
706
|
-
}
|
|
707
|
-
} else {
|
|
708
|
-
console.log('Ethernet interface not found.');
|
|
709
|
-
}
|
|
535
|
+
run();
|
|
710
536
|
});
|
|
711
537
|
|
|
538
|
+
|
|
712
539
|
program
|
|
713
|
-
.command('
|
|
714
|
-
.description('
|
|
715
|
-
.action(
|
|
716
|
-
const interfaces = os.networkInterfaces();
|
|
540
|
+
.command('publish <topic> <message>')
|
|
541
|
+
.description('Publish a message to a NEP+ topic')
|
|
542
|
+
.action((topic, message) => {
|
|
717
543
|
|
|
718
|
-
var
|
|
719
|
-
var callback = function (msg) {
|
|
720
|
-
var date = new Date();
|
|
721
|
-
var dateString = date.toISOString();
|
|
722
|
-
console.log(dateString);
|
|
544
|
+
var openpub = function (master_ip = "127.0.0.1") {
|
|
723
545
|
|
|
724
|
-
|
|
725
|
-
console.log("the message is too long to be displayed");
|
|
726
|
-
} else {
|
|
727
|
-
console.log(msg);
|
|
728
|
-
}
|
|
729
|
-
};
|
|
546
|
+
var pubFunction = function () {
|
|
730
547
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
548
|
+
var msg = message.replace(/'/g, '"')
|
|
549
|
+
console.log(JSON.parse(msg))
|
|
550
|
+
pub.publish(JSON.parse(msg))
|
|
551
|
+
console.log("Message published")
|
|
735
552
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
553
|
+
process.exit(1)
|
|
554
|
+
}
|
|
739
555
|
|
|
740
|
-
let msg = { "input": "topics" };
|
|
741
|
-
var message = JSON.stringify(msg);
|
|
742
|
-
await requester.send(message);
|
|
743
|
-
const [result] = await requester.receive();
|
|
744
|
-
var results = JSON.parse(result.toString());
|
|
745
556
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
console.log("");
|
|
750
|
-
if (results["input"].includes(topic)) {
|
|
751
|
-
opensub(master_ip);
|
|
752
|
-
} else {
|
|
753
|
-
console.log("Topic is not registered");
|
|
754
|
-
}
|
|
755
|
-
}
|
|
557
|
+
var node = new nep.Node("nep-cli-pub")
|
|
558
|
+
var pub = node.new_pub(topic, "json")
|
|
559
|
+
setTimeout(pubFunction, 1000)
|
|
756
560
|
}
|
|
757
561
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
562
|
+
async function run() {
|
|
563
|
+
var requester = new zmq.Request;
|
|
564
|
+
var master_ip = "127.0.0.1"
|
|
565
|
+
|
|
566
|
+
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
567
|
+
|
|
568
|
+
let msg = { "input": "topics" }
|
|
569
|
+
var message = JSON.stringify(msg);
|
|
570
|
+
await requester.send(message)
|
|
571
|
+
const [result] = await requester.receive()
|
|
572
|
+
var results = JSON.parse(result.toString())
|
|
573
|
+
//console.log(results);
|
|
574
|
+
if (results["input"].includes(topic)) {
|
|
575
|
+
console.log("")
|
|
576
|
+
openpub(master_ip)
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
console.log("Topic is not registered");
|
|
765
580
|
}
|
|
766
|
-
} else {
|
|
767
|
-
console.log('Wi-Fi interface not found.');
|
|
768
581
|
}
|
|
582
|
+
run()
|
|
769
583
|
});
|
|
770
584
|
|
|
771
585
|
|
|
772
586
|
program
|
|
773
|
-
.command('
|
|
774
|
-
.description('
|
|
775
|
-
.action(async (topic) => {
|
|
587
|
+
.command('hz <topic> <msg_type>')
|
|
588
|
+
.description('Monitor the publishing rate of a NEP+ topic in localhost')
|
|
589
|
+
.action(async (topic, msg_type) => {
|
|
776
590
|
const interfaces = os.networkInterfaces();
|
|
591
|
+
const master_ip = "127.0.0.1"; // Change to the appropriate master IP
|
|
777
592
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
var date = new Date();
|
|
781
|
-
var dateString = date.toISOString();
|
|
782
|
-
console.log(dateString);
|
|
593
|
+
const opensub = function () {
|
|
594
|
+
const timestamps = []; // To store message timestamps
|
|
783
595
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
596
|
+
const callback = function (msg) {
|
|
597
|
+
const date = new Date();
|
|
598
|
+
const timestamp = date.getTime();
|
|
599
|
+
|
|
600
|
+
timestamps.push(timestamp);
|
|
601
|
+
|
|
602
|
+
// Remove timestamps older than ten seconds
|
|
603
|
+
const tenSecondsAgo = timestamp - 10000;
|
|
604
|
+
while (timestamps[0] < tenSecondsAgo) {
|
|
605
|
+
timestamps.shift();
|
|
788
606
|
}
|
|
789
607
|
};
|
|
790
608
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
var master_ip = "127.0.0.1";
|
|
797
|
-
async function run() {
|
|
798
|
-
var requester = new zmq.Request();
|
|
799
|
-
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
609
|
+
const allowedFormats = ["json", "msgpack", "bytes", "images", "image"];
|
|
610
|
+
const messageFormat = allowedFormats.includes(msg_type) ? msg_type : "json";
|
|
611
|
+
const node = new nep.Node("nep-cli-sub");
|
|
612
|
+
const conf = node.hybrid(master_ip);
|
|
800
613
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
await requester.send(message);
|
|
804
|
-
const [result] = await requester.receive();
|
|
805
|
-
var results = JSON.parse(result.toString());
|
|
614
|
+
console.log("Topic:", topic)
|
|
615
|
+
console.log("Message type:", messageFormat)
|
|
806
616
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
} else {
|
|
810
|
-
console.log("");
|
|
811
|
-
if (results["input"].includes(topic)) {
|
|
812
|
-
opensub(master_ip);
|
|
813
|
-
} else {
|
|
814
|
-
console.log("Topic is not registered");
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
}
|
|
617
|
+
const sub = node.new_sub(topic, messageFormat, callback, conf);
|
|
618
|
+
console.log("");
|
|
818
619
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
.action(async (topic) => {
|
|
826
|
-
const interfaces = os.networkInterfaces();
|
|
827
|
-
|
|
828
|
-
var opensub = function (master_ip = "127.0.0.1") {
|
|
829
|
-
var callback = function (msg) {
|
|
830
|
-
var date = new Date();
|
|
831
|
-
var dateString = date.toISOString();
|
|
832
|
-
console.log(dateString);
|
|
833
|
-
|
|
834
|
-
if (msg.length > 10000) {
|
|
835
|
-
console.log("the message is too long to be displayed");
|
|
836
|
-
} else {
|
|
837
|
-
console.log(msg);
|
|
838
|
-
}
|
|
839
|
-
};
|
|
840
|
-
|
|
841
|
-
var node = new nep.Node("nep-cli-sub");
|
|
842
|
-
var conf = node.hybrid(master_ip);
|
|
843
|
-
sub = node.new_sub(topic, "string", callback, conf);
|
|
844
|
-
};
|
|
845
|
-
|
|
846
|
-
async function run(master_ip) {
|
|
847
|
-
var requester = new zmq.Request();
|
|
848
|
-
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
849
|
-
|
|
850
|
-
let msg = { "input": "topics" };
|
|
851
|
-
var message = JSON.stringify(msg);
|
|
852
|
-
await requester.send(message);
|
|
853
|
-
const [result] = await requester.receive();
|
|
854
|
-
var results = JSON.parse(result.toString());
|
|
855
|
-
|
|
856
|
-
if (results["state"] === "failure") {
|
|
857
|
-
console.log("Topic is not registered");
|
|
858
|
-
} else {
|
|
859
|
-
console.log("");
|
|
860
|
-
if (results["input"].includes(topic)) {
|
|
861
|
-
opensub(master_ip);
|
|
862
|
-
} else {
|
|
863
|
-
console.log("Topic is not registered");
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// Find Ethernet interface
|
|
869
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
870
|
-
if (ethernetInterface) {
|
|
871
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
872
|
-
if (ethernetIPv4) {
|
|
873
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
874
|
-
run(ethernetIPv4.address)
|
|
875
|
-
} else {
|
|
876
|
-
console.log('No Ethernet IPv4 address found.');
|
|
877
|
-
}
|
|
878
|
-
} else {
|
|
879
|
-
console.log('Ethernet interface not found.');
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
|
|
883
|
-
program
|
|
884
|
-
.command('echo-wifi <topic>')
|
|
885
|
-
.description('Subscribe to a NEP+ topic over Wi-Fi and display raw string messages')
|
|
886
|
-
.action(async (topic) => {
|
|
887
|
-
const interfaces = os.networkInterfaces();
|
|
888
|
-
|
|
889
|
-
var opensub = function (master_ip = "127.0.0.1") {
|
|
890
|
-
var callback = function (msg) {
|
|
891
|
-
var date = new Date();
|
|
892
|
-
var dateString = date.toISOString();
|
|
893
|
-
console.log(dateString);
|
|
894
|
-
|
|
895
|
-
if (msg.length > 10000) {
|
|
896
|
-
console.log("the message is too long to be displayed");
|
|
897
|
-
} else {
|
|
898
|
-
console.log(msg);
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
var node = new nep.Node("nep-cli-sub");
|
|
903
|
-
var conf = node.hybrid(master_ip);
|
|
904
|
-
sub = node.new_sub(topic, "string", callback, conf);
|
|
905
|
-
};
|
|
906
|
-
|
|
907
|
-
async function run(master_ip) {
|
|
908
|
-
var requester = new zmq.Request();
|
|
909
|
-
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
910
|
-
|
|
911
|
-
let msg = { "input": "topics" };
|
|
912
|
-
var message = JSON.stringify(msg);
|
|
913
|
-
await requester.send(message);
|
|
914
|
-
const [result] = await requester.receive();
|
|
915
|
-
var results = JSON.parse(result.toString());
|
|
916
|
-
|
|
917
|
-
if (results["state"] === "failure") {
|
|
918
|
-
console.log("Topic is not registered");
|
|
919
|
-
} else {
|
|
920
|
-
console.log("");
|
|
921
|
-
if (results["input"].includes(topic)) {
|
|
922
|
-
opensub(master_ip);
|
|
923
|
-
} else {
|
|
924
|
-
console.log("Topic is not registered");
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
930
|
-
if (wifiInterface) {
|
|
931
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
932
|
-
if (wifiIPv4) {
|
|
933
|
-
run(wifiIPv4.address);
|
|
934
|
-
} else {
|
|
935
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
936
|
-
}
|
|
937
|
-
} else {
|
|
938
|
-
console.log('Wi-Fi interface not found.');
|
|
939
|
-
}
|
|
940
|
-
});
|
|
941
|
-
|
|
942
|
-
program
|
|
943
|
-
.command('publish <topic> <message>')
|
|
944
|
-
.description('Publish a message to a NEP+ topic')
|
|
945
|
-
.action((topic, message) => {
|
|
946
|
-
|
|
947
|
-
var openpub = function (master_ip = "127.0.0.1") {
|
|
948
|
-
|
|
949
|
-
var pubFunction = function () {
|
|
950
|
-
|
|
951
|
-
var msg = message.replace(/'/g, '"')
|
|
952
|
-
console.log(JSON.parse(msg))
|
|
953
|
-
pub.publish(JSON.parse(msg))
|
|
954
|
-
console.log("Message published")
|
|
955
|
-
|
|
956
|
-
process.exit(1)
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
var node = new nep.Node("nep-cli-pub")
|
|
961
|
-
var pub = node.new_pub(topic, "json")
|
|
962
|
-
setTimeout(pubFunction, 1000)
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
async function run() {
|
|
966
|
-
var requester = new zmq.Request;
|
|
967
|
-
var master_ip = "127.0.0.1"
|
|
968
|
-
|
|
969
|
-
requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
|
|
970
|
-
|
|
971
|
-
let msg = { "input": "topics" }
|
|
972
|
-
var message = JSON.stringify(msg);
|
|
973
|
-
await requester.send(message)
|
|
974
|
-
const [result] = await requester.receive()
|
|
975
|
-
var results = JSON.parse(result.toString())
|
|
976
|
-
//console.log(results);
|
|
977
|
-
if (results["input"].includes(topic)) {
|
|
978
|
-
console.log("")
|
|
979
|
-
openpub(master_ip)
|
|
980
|
-
}
|
|
981
|
-
else {
|
|
982
|
-
console.log("Topic is not registered");
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
run()
|
|
986
|
-
});
|
|
987
|
-
|
|
988
|
-
program
|
|
989
|
-
.command('publish-eth <topic> <message>')
|
|
990
|
-
.description('Publish a JSON message to a NEP+ topic over Ethernet')
|
|
991
|
-
.action((topic, message) => {
|
|
992
|
-
|
|
993
|
-
const interfaces = os.networkInterfaces();
|
|
994
|
-
|
|
995
|
-
var openpub = function (master_ip = "127.0.0.1") {
|
|
996
|
-
|
|
997
|
-
var pubFunction = function () {
|
|
998
|
-
|
|
999
|
-
var msg = message.replace(/'/g, '"')
|
|
1000
|
-
console.log(JSON.parse(msg))
|
|
1001
|
-
pub.publish(JSON.parse(msg))
|
|
1002
|
-
console.log("Message published")
|
|
1003
|
-
|
|
1004
|
-
process.exit(1)
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
var node = new nep.Node("nep-cli-pub")
|
|
1009
|
-
var pub = node.new_pub(topic, "json")
|
|
1010
|
-
setTimeout(pubFunction, 1000)
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
async function run(master_ip) {
|
|
1014
|
-
var requester = new zmq.Request();
|
|
1015
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1016
|
-
|
|
1017
|
-
let msg = { "input": "topics" };
|
|
1018
|
-
var message = JSON.stringify(msg);
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
try {
|
|
1022
|
-
await requester.send(message);
|
|
1023
|
-
const [result] = await Promise.race([requester.receive(), timeoutPromise(5000)]); // Timeout of 5 seconds
|
|
1024
|
-
var results = JSON.parse(result.toString());
|
|
1025
|
-
|
|
1026
|
-
if (results["input"].includes(topic)) {
|
|
1027
|
-
console.log("");
|
|
1028
|
-
openpub(master_ip);
|
|
1029
|
-
} else {
|
|
1030
|
-
console.log("Topic is not registered");
|
|
1031
|
-
}
|
|
1032
|
-
} catch (error) {
|
|
1033
|
-
console.error("Error:", error.message);
|
|
1034
|
-
} finally {
|
|
1035
|
-
process.exit(1)
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
1040
|
-
if (ethernetInterface) {
|
|
1041
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
1042
|
-
if (ethernetIPv4) {
|
|
1043
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
1044
|
-
run(ethernetIPv4.address)
|
|
1045
|
-
} else {
|
|
1046
|
-
console.log('No Ethernet IPv4 address found.');
|
|
1047
|
-
}
|
|
1048
|
-
} else {
|
|
1049
|
-
console.log('Ethernet interface not found.');
|
|
1050
|
-
}
|
|
1051
|
-
});
|
|
1052
|
-
|
|
1053
|
-
program
|
|
1054
|
-
.command('publish-wifi <topic> <message>')
|
|
1055
|
-
.description('Publish a JSON message to a NEP+ topic over Wi-Fi')
|
|
1056
|
-
.action((topic, message) => {
|
|
1057
|
-
|
|
1058
|
-
const interfaces = os.networkInterfaces();
|
|
1059
|
-
|
|
1060
|
-
var openpub = function (master_ip = "127.0.0.1") {
|
|
1061
|
-
|
|
1062
|
-
var pubFunction = function () {
|
|
1063
|
-
|
|
1064
|
-
var msg = message.replace(/'/g, '"')
|
|
1065
|
-
console.log(JSON.parse(msg))
|
|
1066
|
-
pub.publish(JSON.parse(msg))
|
|
1067
|
-
console.log("Message published")
|
|
1068
|
-
|
|
1069
|
-
process.exit(1)
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
var node = new nep.Node("nep-cli-pub")
|
|
1074
|
-
var pub = node.new_pub(topic, "json")
|
|
1075
|
-
setTimeout(pubFunction, 1000)
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
async function run(master_ip) {
|
|
1079
|
-
var requester = new zmq.Request();
|
|
1080
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1081
|
-
|
|
1082
|
-
let msg = { "input": "topics" };
|
|
1083
|
-
var message = JSON.stringify(msg);
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
try {
|
|
1087
|
-
await requester.send(message);
|
|
1088
|
-
const [result] = await Promise.race([requester.receive(), timeoutPromise(5000)]); // Timeout of 5 seconds
|
|
1089
|
-
var results = JSON.parse(result.toString());
|
|
1090
|
-
|
|
1091
|
-
if (results["input"].includes(topic)) {
|
|
1092
|
-
console.log("");
|
|
1093
|
-
openpub(master_ip);
|
|
1094
|
-
} else {
|
|
1095
|
-
console.log("Topic is not registered");
|
|
1096
|
-
}
|
|
1097
|
-
} catch (error) {
|
|
1098
|
-
console.error("Error:", error.message);
|
|
1099
|
-
} finally {
|
|
1100
|
-
process.exit(1)
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
1104
|
-
if (wifiInterface) {
|
|
1105
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
1106
|
-
if (wifiIPv4) {
|
|
1107
|
-
console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
|
|
1108
|
-
run(wifiIPv4.address)
|
|
1109
|
-
} else {
|
|
1110
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
1111
|
-
}
|
|
1112
|
-
} else {
|
|
1113
|
-
console.log('Wi-Fi interface not found.');
|
|
1114
|
-
}
|
|
1115
|
-
});
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
program
|
|
1119
|
-
.command('hz <topic>')
|
|
1120
|
-
.description('Monitor the publishing rate of a NEP+ topic in localhost')
|
|
1121
|
-
.action(async (topic) => {
|
|
1122
|
-
const interfaces = os.networkInterfaces();
|
|
1123
|
-
const master_ip = "127.0.0.1"; // Change to the appropriate master IP
|
|
1124
|
-
|
|
1125
|
-
const opensub = function () {
|
|
1126
|
-
const timestamps = []; // To store message timestamps
|
|
1127
|
-
|
|
1128
|
-
const callback = function (msg) {
|
|
1129
|
-
const date = new Date();
|
|
1130
|
-
const timestamp = date.getTime();
|
|
1131
|
-
|
|
1132
|
-
timestamps.push(timestamp);
|
|
1133
|
-
|
|
1134
|
-
// Remove timestamps older than ten seconds
|
|
1135
|
-
const tenSecondsAgo = timestamp - 10000;
|
|
1136
|
-
while (timestamps[0] < tenSecondsAgo) {
|
|
1137
|
-
timestamps.shift();
|
|
1138
|
-
}
|
|
1139
|
-
};
|
|
1140
|
-
|
|
1141
|
-
const messageFormat = topic.endsWith("/image") ? "string" : "string";
|
|
1142
|
-
const node = new nep.Node("nep-cli-sub");
|
|
1143
|
-
const conf = node.hybrid(master_ip);
|
|
1144
|
-
const sub = node.new_sub(topic, messageFormat, callback, conf);
|
|
1145
|
-
|
|
1146
|
-
setInterval(() => {
|
|
1147
|
-
// Calculate statistics for the last 10 seconds
|
|
1148
|
-
const now = Date.now();
|
|
1149
|
-
const tenSecondsAgo = now - 10000;
|
|
1150
|
-
const recentTimestamps = timestamps.filter((ts) => ts > tenSecondsAgo);
|
|
1151
|
-
const rate = recentTimestamps.length / 10; // Messages per second for a 10-second window
|
|
620
|
+
setInterval(() => {
|
|
621
|
+
// Calculate statistics for the last 10 seconds
|
|
622
|
+
const now = Date.now();
|
|
623
|
+
const tenSecondsAgo = now - 10000;
|
|
624
|
+
const recentTimestamps = timestamps.filter((ts) => ts > tenSecondsAgo);
|
|
625
|
+
const rate = recentTimestamps.length / 10; // Messages per second for a 10-second window
|
|
1152
626
|
|
|
1153
627
|
console.log("Average rate:", rate.toFixed(2), "Hz");
|
|
1154
628
|
console.log("Min:", (10 / Math.max(rate, 0.1)).toFixed(2), "s");
|
|
@@ -1213,223 +687,6 @@ program
|
|
|
1213
687
|
});
|
|
1214
688
|
|
|
1215
689
|
|
|
1216
|
-
program
|
|
1217
|
-
.command('hz-wifi <topic>')
|
|
1218
|
-
.description('Monitor the publishing rate of a NEP+ topic over Wi-Fi')
|
|
1219
|
-
.action(async (topic) => {
|
|
1220
|
-
const interfaces = os.networkInterfaces();
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
const opensub = function (master_ip) {
|
|
1224
|
-
const timestamps = []; // To store message timestamps
|
|
1225
|
-
|
|
1226
|
-
const callback = function (msg) {
|
|
1227
|
-
const date = new Date();
|
|
1228
|
-
const timestamp = date.getTime();
|
|
1229
|
-
|
|
1230
|
-
timestamps.push(timestamp);
|
|
1231
|
-
|
|
1232
|
-
// Remove timestamps older than ten seconds
|
|
1233
|
-
const tenSecondsAgo = timestamp - 10000;
|
|
1234
|
-
while (timestamps[0] < tenSecondsAgo) {
|
|
1235
|
-
timestamps.shift();
|
|
1236
|
-
}
|
|
1237
|
-
};
|
|
1238
|
-
|
|
1239
|
-
const messageFormat = topic.endsWith("/image") ? "string" : "string";
|
|
1240
|
-
const node = new nep.Node("nep-cli-sub");
|
|
1241
|
-
const conf = node.hybrid(master_ip);
|
|
1242
|
-
const sub = node.new_sub(topic, messageFormat, callback, conf);
|
|
1243
|
-
|
|
1244
|
-
setInterval(() => {
|
|
1245
|
-
// Calculate statistics for the last 10 seconds
|
|
1246
|
-
const now = Date.now();
|
|
1247
|
-
const tenSecondsAgo = now - 10000;
|
|
1248
|
-
const recentTimestamps = timestamps.filter((ts) => ts > tenSecondsAgo);
|
|
1249
|
-
const rate = recentTimestamps.length / 10; // Messages per second for a 10-second window
|
|
1250
|
-
|
|
1251
|
-
console.log("Average rate:", rate.toFixed(2), "Hz");
|
|
1252
|
-
console.log("Min:", (10 / Math.max(rate, 0.1)).toFixed(2), "s");
|
|
1253
|
-
console.log("Max:", (10 / Math.min(rate, 10)).toFixed(2), "s");
|
|
1254
|
-
console.log("Std dev:", calculateStdDev(recentTimestamps, now).toFixed(2), "s");
|
|
1255
|
-
console.log("Window:", recentTimestamps.length);
|
|
1256
|
-
console.log("");
|
|
1257
|
-
}, 1000);
|
|
1258
|
-
};
|
|
1259
|
-
|
|
1260
|
-
const calculateStdDev = (timestamps) => {
|
|
1261
|
-
if (timestamps.length < 2) {
|
|
1262
|
-
return 0; // Standard deviation is not meaningful with less than two timestamps
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
// Calculate the time intervals between consecutive timestamps
|
|
1266
|
-
const timeIntervals = [];
|
|
1267
|
-
for (let i = 1; i < timestamps.length; i++) {
|
|
1268
|
-
const interval = timestamps[i] - timestamps[i - 1];
|
|
1269
|
-
timeIntervals.push(interval);
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
// Calculate the mean (average) of the time intervals
|
|
1273
|
-
const mean = timeIntervals.reduce((acc, val) => acc + val, 0) / timeIntervals.length;
|
|
1274
|
-
|
|
1275
|
-
// Calculate the squared differences from the mean
|
|
1276
|
-
const squaredDifferences = timeIntervals.map((interval) => Math.pow(interval - mean, 2));
|
|
1277
|
-
|
|
1278
|
-
// Calculate the mean of the squared differences
|
|
1279
|
-
const meanSquaredDifference = squaredDifferences.reduce((acc, val) => acc + val, 0) / squaredDifferences.length;
|
|
1280
|
-
|
|
1281
|
-
// Calculate the square root of the mean squared difference
|
|
1282
|
-
const stdDeviation = Math.sqrt(meanSquaredDifference);
|
|
1283
|
-
|
|
1284
|
-
return stdDeviation;
|
|
1285
|
-
};
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
async function run(master_ip) {
|
|
1289
|
-
const requester = new zmq.Request();
|
|
1290
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1291
|
-
|
|
1292
|
-
const msg = { "input": "topics" };
|
|
1293
|
-
const message = JSON.stringify(msg);
|
|
1294
|
-
await requester.send(message);
|
|
1295
|
-
const [result] = await requester.receive();
|
|
1296
|
-
const results = JSON.parse(result.toString());
|
|
1297
|
-
|
|
1298
|
-
if (results["state"] === "failure") {
|
|
1299
|
-
console.log("Topic is not registered, use *nep topics* to see the list of avaliable topics");
|
|
1300
|
-
} else {
|
|
1301
|
-
console.log("");
|
|
1302
|
-
if (results["input"].includes(topic)) {
|
|
1303
|
-
opensub(master_ip);
|
|
1304
|
-
} else {
|
|
1305
|
-
console.log("Topic is not registered, use *nep topics* to see the list of avaliable topics");
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
|
|
1311
|
-
if (wifiInterface) {
|
|
1312
|
-
const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
|
|
1313
|
-
if (wifiIPv4) {
|
|
1314
|
-
console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
|
|
1315
|
-
run(wifiIPv4.address)
|
|
1316
|
-
} else {
|
|
1317
|
-
console.log('No Wi-Fi IPv4 address found.');
|
|
1318
|
-
}
|
|
1319
|
-
} else {
|
|
1320
|
-
console.log('Wi-Fi interface not found.');
|
|
1321
|
-
}
|
|
1322
|
-
});
|
|
1323
|
-
|
|
1324
|
-
program
|
|
1325
|
-
.command('hz-eth <topic>')
|
|
1326
|
-
.description('Monitor the publishing rate of a NEP+ topic over Ethernet')
|
|
1327
|
-
.action(async (topic) => {
|
|
1328
|
-
const interfaces = os.networkInterfaces();
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
const opensub = function (master_ip) {
|
|
1332
|
-
const timestamps = []; // To store message timestamps
|
|
1333
|
-
|
|
1334
|
-
const callback = function (msg) {
|
|
1335
|
-
const date = new Date();
|
|
1336
|
-
const timestamp = date.getTime();
|
|
1337
|
-
|
|
1338
|
-
timestamps.push(timestamp);
|
|
1339
|
-
|
|
1340
|
-
// Remove timestamps older than ten seconds
|
|
1341
|
-
const tenSecondsAgo = timestamp - 10000;
|
|
1342
|
-
while (timestamps[0] < tenSecondsAgo) {
|
|
1343
|
-
timestamps.shift();
|
|
1344
|
-
}
|
|
1345
|
-
};
|
|
1346
|
-
|
|
1347
|
-
const messageFormat = topic.endsWith("/image") ? "string" : "string";
|
|
1348
|
-
const node = new nep.Node("nep-cli-sub");
|
|
1349
|
-
const conf = node.hybrid(master_ip);
|
|
1350
|
-
const sub = node.new_sub(topic, messageFormat, callback, conf);
|
|
1351
|
-
|
|
1352
|
-
setInterval(() => {
|
|
1353
|
-
// Calculate statistics for the last 10 seconds
|
|
1354
|
-
const now = Date.now();
|
|
1355
|
-
const tenSecondsAgo = now - 10000;
|
|
1356
|
-
const recentTimestamps = timestamps.filter((ts) => ts > tenSecondsAgo);
|
|
1357
|
-
const rate = recentTimestamps.length / 10; // Messages per second for a 10-second window
|
|
1358
|
-
|
|
1359
|
-
console.log("Average rate:", rate.toFixed(2), "Hz");
|
|
1360
|
-
console.log("Min:", (10 / Math.max(rate, 0.1)).toFixed(2), "s");
|
|
1361
|
-
console.log("Max:", (10 / Math.min(rate, 10)).toFixed(2), "s");
|
|
1362
|
-
console.log("Std dev:", calculateStdDev(recentTimestamps, now).toFixed(2), "s");
|
|
1363
|
-
console.log("Window:", recentTimestamps.length);
|
|
1364
|
-
console.log("");
|
|
1365
|
-
}, 1000);
|
|
1366
|
-
};
|
|
1367
|
-
|
|
1368
|
-
const calculateStdDev = (timestamps) => {
|
|
1369
|
-
if (timestamps.length < 2) {
|
|
1370
|
-
return 0; // Standard deviation is not meaningful with less than two timestamps
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// Calculate the time intervals between consecutive timestamps
|
|
1374
|
-
const timeIntervals = [];
|
|
1375
|
-
for (let i = 1; i < timestamps.length; i++) {
|
|
1376
|
-
const interval = timestamps[i] - timestamps[i - 1];
|
|
1377
|
-
timeIntervals.push(interval);
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
// Calculate the mean (average) of the time intervals
|
|
1381
|
-
const mean = timeIntervals.reduce((acc, val) => acc + val, 0) / timeIntervals.length;
|
|
1382
|
-
|
|
1383
|
-
// Calculate the squared differences from the mean
|
|
1384
|
-
const squaredDifferences = timeIntervals.map((interval) => Math.pow(interval - mean, 2));
|
|
1385
|
-
|
|
1386
|
-
// Calculate the mean of the squared differences
|
|
1387
|
-
const meanSquaredDifference = squaredDifferences.reduce((acc, val) => acc + val, 0) / squaredDifferences.length;
|
|
1388
|
-
|
|
1389
|
-
// Calculate the square root of the mean squared difference
|
|
1390
|
-
const stdDeviation = Math.sqrt(meanSquaredDifference);
|
|
1391
|
-
|
|
1392
|
-
return stdDeviation;
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
async function run(master_ip) {
|
|
1397
|
-
const requester = new zmq.Request();
|
|
1398
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1399
|
-
|
|
1400
|
-
const msg = { "input": "topics" };
|
|
1401
|
-
const message = JSON.stringify(msg);
|
|
1402
|
-
await requester.send(message);
|
|
1403
|
-
const [result] = await requester.receive();
|
|
1404
|
-
const results = JSON.parse(result.toString());
|
|
1405
|
-
|
|
1406
|
-
if (results["state"] === "failure") {
|
|
1407
|
-
console.log("Topic is not registered, use *nep topics* to see the list of avaliable topics");
|
|
1408
|
-
} else {
|
|
1409
|
-
console.log("");
|
|
1410
|
-
if (results["input"].includes(topic)) {
|
|
1411
|
-
opensub(master_ip);
|
|
1412
|
-
} else {
|
|
1413
|
-
console.log("Topic is not registered, use *nep topics* to see the list of avaliable topics");
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
|
|
1419
|
-
if (ethernetInterface) {
|
|
1420
|
-
const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
|
|
1421
|
-
if (ethernetIPv4) {
|
|
1422
|
-
console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
|
|
1423
|
-
run(ethernetIPv4.address)
|
|
1424
|
-
} else {
|
|
1425
|
-
console.log('No Ethernet IPv4 address found.');
|
|
1426
|
-
}
|
|
1427
|
-
} else {
|
|
1428
|
-
console.log('Ethernet interface not found.');
|
|
1429
|
-
}
|
|
1430
|
-
});
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
690
|
program
|
|
1434
691
|
.command('docs')
|
|
1435
692
|
.description('Open the NEP+ documentation in the default browser')
|
|
@@ -1444,107 +701,6 @@ program
|
|
|
1444
701
|
}
|
|
1445
702
|
});
|
|
1446
703
|
|
|
1447
|
-
function timeoutPromise(ms) {
|
|
1448
|
-
return new Promise((resolve, reject) => {
|
|
1449
|
-
setTimeout(() => {
|
|
1450
|
-
reject(new Error("Request timed out"));
|
|
1451
|
-
}, ms);
|
|
1452
|
-
});
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
function timeoutPromise(ms) {
|
|
1456
|
-
return new Promise((resolve, reject) => {
|
|
1457
|
-
setTimeout(() => {
|
|
1458
|
-
reject(new Error("Request timed out"));
|
|
1459
|
-
}, ms);
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
async function getAndDisplayTopics(master_ip) {
|
|
1464
|
-
const TIMEOUT_DURATION = 5000;
|
|
1465
|
-
|
|
1466
|
-
var requester = new zmq.Request();
|
|
1467
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1468
|
-
|
|
1469
|
-
let msg = { "input": "topics" };
|
|
1470
|
-
var message = JSON.stringify(msg);
|
|
1471
|
-
|
|
1472
|
-
try {
|
|
1473
|
-
const responsePromise = new Promise(async (resolve, reject) => {
|
|
1474
|
-
await requester.send(message);
|
|
1475
|
-
const [result] = await requester.receive();
|
|
1476
|
-
var results = JSON.parse(result.toString());
|
|
1477
|
-
resolve(results);
|
|
1478
|
-
});
|
|
1479
|
-
|
|
1480
|
-
const timeoutPromise = new Promise((resolve, reject) => {
|
|
1481
|
-
setTimeout(() => {
|
|
1482
|
-
reject(new Error("Timed out, NEP master over Wi-Fi was not found"));
|
|
1483
|
-
}, TIMEOUT_DURATION);
|
|
1484
|
-
});
|
|
1485
|
-
|
|
1486
|
-
const results = await Promise.race([responsePromise, timeoutPromise]);
|
|
1487
|
-
|
|
1488
|
-
if (results["state"] === "success") {
|
|
1489
|
-
availableTopics = results["input"];
|
|
1490
|
-
console.log("");
|
|
1491
|
-
results["input"].forEach(element => {
|
|
1492
|
-
console.log(element);
|
|
1493
|
-
});
|
|
1494
|
-
} else {
|
|
1495
|
-
console.log("No topics yet");
|
|
1496
|
-
}
|
|
1497
|
-
} catch (error) {
|
|
1498
|
-
console.error("Error:", error.message);
|
|
1499
|
-
} finally {
|
|
1500
|
-
process.exit();
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
async function getAndDisplayTopics(master_ip) {
|
|
1508
|
-
const TIMEOUT_DURATION = 5000;
|
|
1509
|
-
|
|
1510
|
-
var requester = new zmq.Request();
|
|
1511
|
-
requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
|
|
1512
|
-
|
|
1513
|
-
let msg = { "input": "topics" };
|
|
1514
|
-
var message = JSON.stringify(msg);
|
|
1515
|
-
|
|
1516
|
-
try {
|
|
1517
|
-
const responsePromise = new Promise(async (resolve, reject) => {
|
|
1518
|
-
await requester.send(message);
|
|
1519
|
-
const [result] = await requester.receive();
|
|
1520
|
-
var results = JSON.parse(result.toString());
|
|
1521
|
-
resolve(results);
|
|
1522
|
-
});
|
|
1523
|
-
|
|
1524
|
-
const timeoutPromise = new Promise((resolve, reject) => {
|
|
1525
|
-
setTimeout(() => {
|
|
1526
|
-
reject(new Error("Timed out, NEP master over Ethernet was not found"));
|
|
1527
|
-
}, TIMEOUT_DURATION);
|
|
1528
|
-
});
|
|
1529
|
-
|
|
1530
|
-
const results = await Promise.race([responsePromise, timeoutPromise]);
|
|
1531
|
-
|
|
1532
|
-
if (results["state"] === "success") {
|
|
1533
|
-
availableTopics = results["input"];
|
|
1534
|
-
console.log("");
|
|
1535
|
-
results["input"].forEach(element => {
|
|
1536
|
-
console.log(element);
|
|
1537
|
-
});
|
|
1538
|
-
} else {
|
|
1539
|
-
console.log("No topics yet");
|
|
1540
|
-
}
|
|
1541
|
-
} catch (error) {
|
|
1542
|
-
console.error("Error:", error.message);
|
|
1543
|
-
} finally {
|
|
1544
|
-
process.exit();
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
|
|
1548
704
|
|
|
1549
705
|
program.parse(process.argv);
|
|
1550
706
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nep-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"main": "./lib/nep.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"nep": "./bin/index.js"
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"express": "^4.18.2",
|
|
15
15
|
"fix-path": "^2.1.0",
|
|
16
16
|
"inquirer": "^9.2.10",
|
|
17
|
-
"nep-js": "
|
|
17
|
+
"nep-js": "0.3.7",
|
|
18
18
|
"open": "7.4.2",
|
|
19
19
|
"socket.io": "^4.7.2",
|
|
20
|
-
"zeromq": "6.0.0-beta.
|
|
20
|
+
"zeromq": "6.0.0-beta.19"
|
|
21
21
|
}
|
|
22
22
|
}
|