nep-cli 0.1.9 → 0.2.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/bin/index.js CHANGED
@@ -5,7 +5,7 @@ const { version } = require('../package.json');
5
5
  const os = require('os');
6
6
  const zmq = require("zeromq");
7
7
  var nep = require('nep-js');
8
- var nep_configuration = { current_port: 10000, IP: "0.0.0.0", brokers: {} }
8
+ var nep_configuration = { current_port: 50200, IP: "0.0.0.0", brokers: {} }
9
9
  const { exec } = require('child_process');
10
10
  const { AutoComplete } = require('enquirer');
11
11
 
@@ -17,64 +17,48 @@ const socketIo = require('socket.io');
17
17
  const fs = require('fs');
18
18
  const zmqc = require("zeromq/v5-compat");
19
19
 
20
+ const PORT_MASTER_INFO = 50001; // Default port for master info
21
+ const PORT_IMAGES = 50060;
22
+ const PORT_JSON = 50080;
20
23
 
21
- program
22
- .version(version)
23
- .description('NEP-CLI')
24
-
25
-
26
- function getIPAddress(interfaceName) {
27
- const interfaces = os.networkInterfaces();
28
- const networkInterface = interfaces[interfaceName];
29
-
30
- if (networkInterface) {
31
- const ipAddressInfo = networkInterface.find(info => info.family === 'IPv4');
32
- return ipAddressInfo ? ipAddressInfo.address : null;
33
- } else {
34
- return null;
35
- }
36
- }
37
24
 
38
- function printIPAddress(interfaceName, ipAddress) {
39
- if (ipAddress) {
40
- console.log(`${interfaceName} IP Address: ${ipAddress}`);
41
- } else {
42
- console.log(`No ${interfaceName} IPv4 address found.`);
43
- }
44
- }
25
+ program
26
+ .version(version)
27
+ .description('NEP-CLI')
45
28
 
46
29
  program
47
- .command('ip')
48
- .description('Display current Wi-Fi and Ethernet IP addresses of this computer')
49
- .action(() => {
50
- try {
51
- const platform = os.platform();
52
- let wifiInterfaces, ethernetInterface;
53
-
54
- if (platform === 'linux') {
55
- wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(wlan|wlp|wl|en)\d*$/i.test(ifname));
56
- ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^(eth|enp|eno)\d*$/i.test(ifname));
57
- } else if (platform === 'win32') {
58
- wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(Wireless|Wi-Fi)/i.test(ifname));
59
- ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^Ethernet/i.test(ifname));
60
- } else if (platform === 'darwin') {
61
- wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^en\d*$/i.test(ifname));
62
- ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^en\d*$/i.test(ifname));
63
- } else {
64
- console.log('Unsupported operating system.');
65
- return;
66
- }
30
+ .command('ip')
31
+ .description('Display current Wi-Fi and Ethernet IP addresses of this computer')
32
+ .action(() => {
33
+ try {
34
+ // subsitude by interfaces = nep.getNetworkInterfaces --> {"wifi":wifiInterfaces, "eth":ethernetInterface}
35
+ const platform = os.platform();
36
+ let wifiInterfaces, ethernetInterface;
37
+
38
+ if (platform === 'linux') {
39
+ wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(wlan|wlp|wl|en)\d*$/i.test(ifname));
40
+ ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^(eth|enp|eno)\d*$/i.test(ifname));
41
+ } else if (platform === 'win32') {
42
+ wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^(Wireless|Wi-Fi)/i.test(ifname));
43
+ ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^Ethernet/i.test(ifname));
44
+ } else if (platform === 'darwin') {
45
+ wifiInterfaces = Object.keys(os.networkInterfaces()).filter(ifname => /^en\d*$/i.test(ifname));
46
+ ethernetInterface = Object.keys(os.networkInterfaces()).find(ifname => /^en\d*$/i.test(ifname));
47
+ } else {
48
+ console.log('Unsupported operating system.');
49
+ return;
50
+ }
67
51
 
68
- wifiInterfaces.forEach(wifiInterface => {
69
- const ipAddress = getIPAddress(wifiInterface);
70
- printIPAddress(`Wi-Fi (${wifiInterface})`, ipAddress);
71
- });
52
+ wifiInterfaces.forEach(wifiInterface => {
53
+ const ipAddress = nep.getIPAddress(wifiInterface);
54
+ nep.printIPAddress(`Wi-Fi (${wifiInterface})`, ipAddress);
55
+ });
72
56
 
73
- printIPAddress('Ethernet', getIPAddress(ethernetInterface));
74
- } catch (error) {
75
- console.error('An error occurred:', error.message);
76
- }
77
- });
57
+ nep.printIPAddress('Ethernet', nep.getIPAddress(ethernetInterface));
58
+ } catch (error) {
59
+ console.error('An error occurred:', error.message);
60
+ }
61
+ });
78
62
 
79
63
 
80
64
 
@@ -85,7 +69,7 @@ var nodes_register = {};
85
69
  var topic_register = {};
86
70
 
87
71
  class MasterLocal {
88
- constructor(IP = '0.0.0.0', port_ = 7000) {
72
+ constructor(IP = '0.0.0.0', port_ = 50000) {
89
73
  this.port = String(port_)
90
74
  var address = "tcp://" + IP + ":" + this.port
91
75
  console.log("New Master in: " + address)
@@ -266,60 +250,118 @@ var restartTopics = function (node_request) {
266
250
  onUpdateTopicList(topic_register)
267
251
  }
268
252
 
269
- var processMsg = function (json_msg, nodes_register, topic_register) {
270
-
271
- let node_request = JSON.parse(json_msg)
272
- console.log("NEP : Node request - node: " + node_request["node"] + ", socket: " + node_request["socket"] + ", topic: " + node_request["topic"])
253
+ const processMsg = (json_msg, nodes_register, topic_register) => {
254
+ const node_request = JSON.parse(json_msg);
255
+ const { node, socket, topic, pid } = node_request;
256
+ console.log(`NEP: Node request - node: ${node}, socket: ${socket}, topic: ${topic}`);
273
257
 
274
258
  // Check node status
275
- if ('node' in node_request) {
276
-
259
+ if (node) {
277
260
  // Kill previous node with the same name
278
- if (node_request['node'] in nodes_register) {
279
-
280
- console.log("--- Node *" + node_request['node'] + "* already defined ---")
281
- var current_pid = nodes_register[node_request['node']]
282
- if (node_request['pid'] === current_pid) {
283
-
284
- }
285
- else {
286
- // TODO -- reset topics in node for graph
287
- console.log("Kill node: " + node_request['node'])
288
- nep.killNode(current_pid)
261
+ if (node in nodes_register) {
262
+ console.log(`--- Node *${node}* already defined ---`);
263
+ const current_pid = nodes_register[node];
264
+ if (pid !== current_pid) {
265
+ if (!node.startsWith('nep-cli')) {
266
+ // TODO: Reset topics in node for graph
267
+ console.log(`Kill node: ${node}`);
268
+ nep.killNode(current_pid);
269
+ }
289
270
  }
290
- }
291
- else {
292
- console.log("--- New Node *" + node_request['node'] + "* ---")
271
+ } else {
272
+ console.log(`--- New Node *${node}* ---`);
293
273
  }
294
274
  }
295
275
 
296
276
  // Update node info
297
- nodes_register[node_request['node']] = node_request['pid']
298
- // Get topic name
299
- var topic = String(node_request['topic'])
300
- // Check topic status
301
- if (topic in topic_register) {
302
- console.log("--- Topic *" + topic + "* already registered --- ")
277
+ nodes_register[node] = pid;
303
278
 
279
+ // Check topic status
280
+ const topicStr = String(topic);
281
+ if (topicStr in topic_register) {
282
+ console.log(`--- Topic *${topicStr}* already registered ---`);
304
283
  // Send information of topic already defined
305
- var response = onRegisteredTopic(node_request, topic_register, topic)
306
- return JSON.stringify(response)
307
- }
308
- else {
309
- console.log(" --- New topic : *" + topic + "* ---")
284
+ const response = onRegisteredTopic(node_request, topic_register, topicStr);
285
+ return JSON.stringify(response);
286
+ } else {
287
+ console.log(`--- New topic: *${topicStr}* ---`);
310
288
  // Create new broker
311
- var response = onNewTopic(node_request, topic_register);
312
- return JSON.stringify(response)
289
+ const response = onNewTopic(node_request, topic_register);
290
+ return JSON.stringify(response);
313
291
  }
314
- }
292
+ };
293
+
294
+ function startShowServer(port, topic, ip) {
295
+ const app = express();
296
+ const server = http.createServer(app);
297
+ const io = socketIo(server);
298
+ const path = require('path');
315
299
 
316
- const PORT_MASTER_INFO = 7010; // Default port for master info
317
- const PORT_IMAGE = 3000;
318
- const PORT_IMAGES = [];
319
- for (let i = 3020; i <= 3040; i++) {
320
- PORT_IMAGES.push(i);
300
+ const node = new nep.Node("nep-cli-sub");
301
+ const config = node.hybrid(ip)
302
+
303
+ function getImage(msg) {
304
+ // Send the received image data as-is to connected clients
305
+ io.sockets.emit('image', { image: msg });
306
+ }
307
+
308
+ const sub = node.new_sub(topic, "images", getImage, config);
309
+
310
+ app.get('/', (req, res) => {
311
+ res.sendFile(path.join(__dirname, './image.html')); // Serve your HTML file
312
+ });
313
+
314
+ server.listen(port, () => {
315
+ console.log(`Server is running on http://localhost:${port}`);
316
+ }).on('error', err => {
317
+ console.error(`Error starting server: ${err}`);
318
+ });
319
+
320
+ io.on('connection', (socket) => {
321
+ const frameRate = 30; // Desired frame rate
322
+ const interval = 1000 / frameRate; // Interval between frames
323
+ }).on('error', err => {
324
+ console.error(`Error with socket connection: ${err}`);
325
+ });
321
326
  }
322
327
 
328
+ function startJsonServer(port, topic, ip, msg_type = "json") {
329
+ const app = express();
330
+ const server = http.createServer(app);
331
+ const io = socketIo(server);
332
+ const path = require('path');
333
+
334
+ const node = new nep.Node("nep-cli-sub");
335
+ const config = node.hybrid(ip)
336
+
337
+ function getJSON(msg) {
338
+ try {
339
+
340
+ io.sockets.emit('json_data', msg);
341
+ } catch (error) {
342
+
343
+ }
344
+ }
345
+
346
+ const sub = node.new_sub(topic, msg_type, getJSON, config);
347
+
348
+ app.get('/', (req, res) => {
349
+ res.sendFile(path.join(__dirname, './json.html')); // Serve your HTML file
350
+ });
351
+
352
+ server.listen(port, () => {
353
+ console.log(`Server is running on http://localhost:${port}`);
354
+ }).on('error', err => {
355
+ console.error(`Error starting server: ${err}`);
356
+ });
357
+
358
+ io.on('connection', (socket) => {
359
+ const frameRate = 30; // Desired frame rate
360
+ const interval = 1000 / frameRate; // Interval between frames
361
+ }).on('error', err => {
362
+ console.error(`Error with socket connection: ${err}`);
363
+ });
364
+ }
323
365
 
324
366
 
325
367
  program
@@ -397,7 +439,7 @@ program
397
439
  var node = new nep.Node("nep-cli");
398
440
  console.log("Starting NEP master in terminal")
399
441
  var master = new MasterLocal();
400
- var info = new nep.MasterInfoServer(IP = '0.0.0.0', topics = topic_register);
442
+ var info = new nep.MasterInfoServer(IP = '0.0.0.0', topics = topic_register, port_ = PORT_MASTER_INFO);
401
443
  } catch (error) {
402
444
  if (error.message.includes('EADDRINUSE')) {
403
445
  console.error("Error: Address already in use. Another instance of NEP master might be running.");
@@ -461,65 +503,45 @@ program
461
503
  await getTopics(); // Call the function to get topics
462
504
  });
463
505
 
506
+ program
507
+ .command('show <topic> <msg_type> [index]')
508
+ .description('Show images published to a NEP+ topic in the default browser')
509
+ .action(async (topic, msg_type, index = 0) => {
510
+ const ip = "127.0.0.1";
511
+ const topicid = `${topic}`;
512
+ const port = PORT_IMAGES + parseInt(index);
513
+
514
+ const allowedFormats = ["json", "images", "dictionary"];
515
+ if (!allowedFormats.includes(msg_type)) {
516
+ console.error(`Format '${msg_type}' no allowed. Allowed formats are: ${allowedFormats.join(', ')}`);
517
+ return;
518
+ }
464
519
 
465
- program
466
- .command('listen <topic>')
467
- .description('Subscribe to a NEP+ topic and display JSON messages')
468
- .action(async (topic) => {
469
- const interfaces = os.networkInterfaces();
470
-
471
- var opensub = function (master_ip = "127.0.0.1") {
472
- var callback = function (msg) {
473
- var date = new Date();
474
- var dateString = date.toISOString();
475
- console.log(dateString);
476
-
477
- if (msg.length > 10000) {
478
- console.log("the message is too long to be displayed");
479
- } else {
480
- console.log(msg);
481
- }
482
- };
520
+ if(msg_type === "images"){
521
+ open(`http://localhost:${port}/?port=${port}&topic=${encodeURIComponent(topicid)}`);
522
+ startShowServer(port, topic, ip);
523
+ }
524
+ else if (msg_type === "json" || msg_type === "dictionary")
525
+ {
526
+ open(`http://localhost:${port}/?port=${port}&topic=${encodeURIComponent(topicid)}`);
527
+ startJsonServer(port, topic, ip, msg_type);
528
+ }
529
+ });
483
530
 
484
- var node = new nep.Node("nep-cli-sub");
485
- var conf = node.hybrid(master_ip);
486
- sub = node.new_sub(topic, "json", callback, conf);
487
- };
531
+ program
532
+ .command('echo <topic> <msg_type>')
533
+ .description('Subscribe to a NEP+ topic and display raw string messages')
534
+ .action(async (topic, msg_type) => {
488
535
 
489
- var master_ip = "127.0.0.1";
490
- async function run() {
491
- var requester = new zmq.Request();
492
- requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
493
536
 
494
- let msg = { "input": "topics" };
495
- var message = JSON.stringify(msg);
496
- await requester.send(message);
497
- const [result] = await requester.receive();
498
- var results = JSON.parse(result.toString());
499
537
 
500
- if (results["state"] === "failure") {
501
- console.log("Topic is not registered");
502
- } else {
503
- console.log("");
504
- if (results["input"].includes(topic)) {
505
- opensub(master_ip);
506
- } else {
507
- console.log("Topic is not registered");
508
- }
509
- }
538
+ const allowedFormats = ["json", "msgpack", "bytes", "images", "dictionary", "string"];
539
+ if (!allowedFormats.includes(msg_type)) {
540
+ console.error(`Format '${msg_type}' no allowed. Allowed formats are: ${allowedFormats.join(', ')}`);
541
+ return;
510
542
  }
511
543
 
512
- run();
513
- });
514
-
515
-
516
- program
517
- .command('echo <topic>')
518
- .description('Subscribe to a NEP+ topic and display raw string messages')
519
- .action(async (topic) => {
520
- const interfaces = os.networkInterfaces();
521
-
522
- var opensub = function (master_ip = "127.0.0.1") {
544
+ var opensub = function (master_ip = "127.0.0.1", msg_type) {
523
545
  var callback = function (msg) {
524
546
  var date = new Date();
525
547
  var dateString = date.toISOString();
@@ -534,9 +556,10 @@ program
534
556
 
535
557
  var node = new nep.Node("nep-cli-sub");
536
558
  var conf = node.hybrid(master_ip);
537
- sub = node.new_sub(topic, "string", callback, conf);
559
+ sub = node.new_sub(topic, msg_type, callback, conf);
538
560
  };
539
561
 
562
+
540
563
  var master_ip = "127.0.0.1";
541
564
  async function run() {
542
565
  var requester = new zmq.Request();
@@ -553,7 +576,7 @@ program
553
576
  } else {
554
577
  console.log("");
555
578
  if (results["input"].includes(topic)) {
556
- opensub(master_ip);
579
+ opensub(master_ip, msg_type);
557
580
  } else {
558
581
  console.log("Topic is not registered");
559
582
  }
@@ -563,54 +586,6 @@ program
563
586
  run();
564
587
  });
565
588
 
566
-
567
- program
568
- .command('publish <topic> <message>')
569
- .description('Publish a message to a NEP+ topic')
570
- .action((topic, message) => {
571
-
572
- var openpub = function (master_ip = "127.0.0.1") {
573
-
574
- var pubFunction = function () {
575
-
576
- var msg = message.replace(/'/g, '"')
577
- console.log(JSON.parse(msg))
578
- pub.publish(JSON.parse(msg))
579
- console.log("Message published")
580
-
581
- process.exit(1)
582
- }
583
-
584
-
585
- var node = new nep.Node("nep-cli-pub")
586
- var pub = node.new_pub(topic, "json")
587
- setTimeout(pubFunction, 1000)
588
- }
589
-
590
- async function run() {
591
- var requester = new zmq.Request;
592
- var master_ip = "127.0.0.1"
593
-
594
- requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
595
-
596
- let msg = { "input": "topics" }
597
- var message = JSON.stringify(msg);
598
- await requester.send(message)
599
- const [result] = await requester.receive()
600
- var results = JSON.parse(result.toString())
601
- //console.log(results);
602
- if (results["input"].includes(topic)) {
603
- console.log("")
604
- openpub(master_ip)
605
- }
606
- else {
607
- console.log("Topic is not registered");
608
- }
609
- }
610
- run()
611
- });
612
-
613
-
614
589
  program
615
590
  .command('hz <topic> <msg_type>')
616
591
  .description('Monitor the publishing rate of a NEP+ topic in localhost')
@@ -634,15 +609,18 @@ program
634
609
  }
635
610
  };
636
611
 
637
- const allowedFormats = ["json", "msgpack", "bytes", "images", "image"];
638
- const messageFormat = allowedFormats.includes(msg_type) ? msg_type : "json";
612
+ const allowedFormats = ["json", "msgpack", "bytes", "images", "dictionary", "string"];
613
+ if (!allowedFormats.includes(msg_type)) {
614
+ console.error(`Format '${msg_type}' no allowed. Allowed formats are: ${allowedFormats.join(', ')}`);
615
+ return;
616
+ }
639
617
  const node = new nep.Node("nep-cli-sub");
640
618
  const conf = node.hybrid(master_ip);
641
619
 
642
620
  console.log("Topic:", topic)
643
- console.log("Message type:", messageFormat)
621
+ console.log("Message type:", msg_type)
644
622
 
645
- const sub = node.new_sub(topic, messageFormat, callback, conf);
623
+ const sub = node.new_sub(topic, msg_type, callback, conf);
646
624
  console.log("");
647
625
 
648
626
  setInterval(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nep-cli",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
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": "0.3.5",
17
+ "nep-js": "0.3.8",
18
18
  "open": "7.4.2",
19
19
  "socket.io": "^4.7.2",
20
- "zeromq": "6.0.0-beta.6"
20
+ "zeromq": "6.0.0-beta.19"
21
21
  }
22
22
  }
package/bin/image4.html DELETED
@@ -1,57 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>NEP+ Image</title>
8
- <!-- Include Vue 2 and Vuetify 2 from CDN -->
9
- <link href="https://cdn.jsdelivr.net/npm/vuetify@2.6.3/dist/vuetify.min.css" rel="stylesheet">
10
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
11
- <script src="https://cdn.jsdelivr.net/npm/vuetify@2.6.3/dist/vuetify.js"></script>
12
- </head>
13
-
14
- <body>
15
- <div id="app">
16
- <v-app>
17
- <v-container>
18
- <v-toolbar dense color="transparent">
19
- <v-toolbar-title>Camera USB</v-toolbar-title>
20
- <v-spacer></v-spacer>
21
-
22
- </v-toolbar>
23
- <v-row>
24
- <v-col>
25
- <v-card color="#1A1A1A">
26
- <v-img :src="imageSrc" alt="Streamed Image" contain></v-img>
27
- </v-card>
28
- </v-col>
29
- </v-row>
30
- </v-container>
31
- </v-app>
32
- </div>
33
- <script src="/socket.io/socket.io.js"></script> <!-- Include the Socket.IO client library -->
34
- <script>
35
- // Initialize Vue and Vuetify
36
- new Vue({
37
- el: '#app',
38
- vuetify: new Vuetify(),
39
- data() {
40
- return {
41
- imageSrc: '', // Initialize the image source as empty
42
- };
43
- },
44
- mounted() {
45
- const image = document.getElementById('image');
46
- const socket = io.connect('http://localhost:3000'); // Connect to your server
47
-
48
- socket.on('image', (data) => {
49
- // Set the received image data as the image source
50
- this.imageSrc = `data:image/jpeg;base64,${data.image}`;
51
- });
52
- },
53
- });
54
- </script>
55
- </body>
56
-
57
- </html>