nep-cli 0.1.1 → 0.1.3

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.
Files changed (2) hide show
  1. package/bin/index.js +999 -834
  2. package/package.json +20 -16
package/bin/index.js CHANGED
@@ -1,834 +1,999 @@
1
- #!/usr/bin/env node
2
-
3
- //console.log("You are using nep-cli :)")
4
- var args = process.argv.splice(process.execArgv.length + 2);
5
-
6
-
7
- var zmq = require("zeromq");
8
- var zmqc = require("zeromq/v5-compat");
9
- var nep = require('nep-js');
10
-
11
- // Retrieve the first argument
12
- var value = args[0];
13
- var value1 = "";
14
- var value2 = "";
15
- var value3 = "";
16
-
17
- try {
18
- value1 = args[1];
19
- value2 = args[2];
20
- value3 = args[3];
21
- } catch (error) {
22
- value1 = "";
23
- value2 = "";
24
- value3 = "";
25
- }
26
-
27
- var PORT_DISCOVER = 7777
28
- var PORT_MASTER = 7000
29
- var PORT_MASTER_INFO = 7010
30
-
31
- var devices = {};
32
- var devices_ethernet = {};
33
- var watch = {};
34
- var watch_ethernet = {};
35
- var timerDiscoverWifi = "";
36
- var timerDiscoverEthernet = "";
37
- var nep_configuration = { current_port: 10000, IP: "127.0.0.1", brokers: {} }
38
-
39
-
40
- function dicovery_send() {
41
-
42
- var dgram = require("dgram");
43
- var devices = [];
44
-
45
- var ips = nep.getIP();
46
- var IP_EXTERNAL = ips.wifi;
47
- var IP_LAN = ips.ethernet;
48
-
49
- const search = new Buffer([
50
- 'M-SEARCH * HTTP/1.1',
51
- 'HOST: 239.255.255.250:1900',
52
- 'MAN: "ssdp:discover"',
53
- 'MX: 3',
54
- 'ST: upnp:rootdevice'
55
- ].join('\r\n'));
56
-
57
- const socket = dgram.createSocket('udp4');
58
- socket.on('listening', () => {
59
- socket.addMembership('239.255.255.250');
60
- socket.send(search, 0, search.length, 1900, "239.255.255.250");
61
- });
62
-
63
-
64
- function discover_lan() {
65
- socket.send(search, 0, search.length, 1900, "239.255.255.250");
66
- }
67
- timerDiscoverEthernet = setInterval(discover_lan, 1000);
68
-
69
- socket.bind(1900);
70
-
71
-
72
- }
73
-
74
-
75
- function dicovery_server() {
76
-
77
- var dgram = require("dgram");
78
- var node = new nep.Node("nep-cli-ipdiscover");
79
- var pub = node.new_pub("ipdiscover", "json");
80
-
81
- var devices = [];
82
-
83
- var ips = nep.getIP();
84
- var IP_EXTERNAL = ips.wifi;
85
- var IP_LAN = ips.ethernet;
86
-
87
- const socket = dgram.createSocket('udp4');
88
- socket.on('listening', () => {
89
- socket.addMembership('239.255.255.250');
90
- });
91
- socket.on('message', (message, rinfo) => {
92
- if (!(devices.includes(rinfo.address))) {
93
- if (!(rinfo.address === IP_EXTERNAL)) {
94
- devices.push(rinfo.address)
95
- }
96
- }
97
- console.log(devices)
98
- try {
99
- pub.publish({ "devices": devices })
100
- } catch (error) {
101
- console.log("NEP master not avaliable")
102
- }
103
- });
104
- socket.bind(1900);
105
-
106
-
107
-
108
-
109
-
110
-
111
- }
112
-
113
-
114
-
115
- function discoverable() {
116
- var ips = nep.getIP();
117
- var IP_EXTERNAL = ips.wifi;
118
- var IP_LAN = ips.ethernet;
119
- var node = new nep.Node("nep-cli-discoverable");
120
-
121
- if (IP_EXTERNAL == "") {
122
- console.log("No Wi-fi connection")
123
- }
124
- else {
125
- var pub_list = nep.setHostsPublishers(IP_EXTERNAL, node);
126
- function discover_wifi() {
127
- nep.publishDevices(topic_register, pub_list, IP_EXTERNAL)
128
- }
129
- timerDiscoverWifi = setInterval(discover_wifi, 1000);
130
-
131
- }
132
-
133
- if (IP_LAN == "") {
134
- console.log("No Ethernet connection")
135
- }
136
- else {
137
- var pub_list_lan = nep.setHostsPublishers(IP_LAN, node);
138
- function discover_lan() {
139
- nep.publishDevices(topic_register, pub_list_lan, IP_EXTERNAL)
140
- }
141
- timerDiscoverEthernet = setInterval(discover_lan, 1000);
142
- }
143
-
144
- }
145
-
146
-
147
- function getWifi() {
148
-
149
- var ips = nep.getIP();
150
-
151
- if (ips.wifi == "") {
152
-
153
- console.log("No Wi-fi")
154
-
155
- }
156
- else {
157
- var node = new nep.Node("nep-cli-wifi");
158
- var conf = node.direct(ips.wifi, PORT_DISCOVER, "many2one");
159
-
160
- var callback_remote_sub = function (msg) {
161
- devices[msg.computer] = { "ip": msg.ip, "avaliable": true }
162
- watch[msg.computer] = msg.timestamp
163
-
164
- }
165
-
166
- var watchdevices = function (msg) {
167
- for (device in watch) {
168
- var difference = Math.abs(Date.now() - watch[device])
169
- if (difference > 5 * 1000) {
170
- devices[device]["avaliable"] = false
171
- }
172
-
173
- }
174
-
175
- }
176
- var timerCleanWifi = setInterval(watchdevices, 1000);
177
- sub_remote = node.new_sub("master_ex", "json", callback_remote_sub, conf);
178
-
179
- }
180
-
181
- }
182
-
183
- function getEthernet() {
184
-
185
- var ips = nep.getIP();
186
-
187
- if (ips.ethernet == "") {
188
-
189
- console.log("No Ethernet")
190
-
191
- }
192
- else {
193
-
194
- var node = new nep.Node("nep-cli-ethernet");
195
- var conf = node.direct(ips.ethernet, PORT_DISCOVER, "many2one");
196
-
197
- var callback_remote_sub_et = function (msg) {
198
- devices_ethernet[msg.computer] = { "ip": msg.ip, "avaliable": true }
199
- watch_ethernet[msg.computer] = msg.timestamp
200
-
201
- }
202
-
203
- var watchdevices_et = function (msg) {
204
- for (device in watch) {
205
- var difference = Math.abs(Date.now() - watch_ethernet[device])
206
- if (difference > 5 * 1000) {
207
- devices_ethernet[device]["avaliable"] = false
208
- }
209
-
210
- }
211
-
212
- }
213
- var timerCleanET = setInterval(watchdevices_et, 1000);
214
- sub_remote_et = node.new_sub("master_ex", "json", callback_remote_sub_et, conf);
215
-
216
- }
217
-
218
-
219
- }
220
-
221
-
222
-
223
- if (value == "master") {
224
-
225
- var node = new nep.Node("nep-cli");
226
-
227
- console.log("Starting NEP master in terminal")
228
-
229
- // ----------- Main variables ---------------
230
- // Topics saved here
231
- var topic_register = {};
232
- // Node saved here
233
- var nodes_register = {};
234
-
235
-
236
-
237
-
238
-
239
- class MasterLocal {
240
- constructor(IP = '127.0.0.1', port_ = 7000) {
241
- this.port = String(port_)
242
- var address = "tcp://" + IP + ":" + this.port
243
- console.log("New Master in: " + address)
244
- try {
245
- async function run() {
246
- const reply = new zmq.Reply
247
- await reply.bind(address)
248
- for await (const [node_request] of reply) {
249
- await reply.send(processMsg(node_request, nodes_register, topic_register))
250
- }
251
- }
252
- run()
253
- } catch (error) {
254
- }
255
- }
256
- }
257
-
258
- var onRegisteredTopic = function (node_request, topic_register, topic) {
259
-
260
- var msg = { "state": "failure" }
261
-
262
- try {
263
- var port = topic_register[topic]["port"]
264
- var socket_ = topic_register[topic]["socket"]
265
-
266
- if ("mode" in topic_register[topic]) {
267
- var mode = topic_register[topic]["mode"]
268
- msg = { 'topic': topic, 'port': port, 'mode': mode, 'ip': nep_configuration["IP"], 'socket': socket_, "state": "success" }
269
- }
270
- else {
271
- msg = { 'topic': topic, 'port': port, 'ip': nep_configuration["IP"], 'socket': socket_, "state": "success" }
272
- }
273
- updatePID(node_request, topic_register, topic)
274
-
275
- } catch (error) {
276
- console.log("Error in topic request")
277
- }
278
-
279
- if ("language" in node_request) {
280
-
281
- if (node_request["language"] == "C++") {
282
- msg.port = msg.port.toString();
283
- }
284
-
285
- }
286
-
287
- return msg
288
- }
289
-
290
-
291
- var onResetTopic = function (node_request) {
292
-
293
- var topic = node_request["topic"]
294
- nep_configuration["current_port"] = Math.max(nep_configuration["current_port"], node_request["port"] + 2);
295
-
296
- if (node_request["socket"] === "publisher" || node_request["socket"] === "subscriber") {
297
- // Create new broker for many2many communication
298
- if (node_request["mode"] === "many2many") {
299
- restartBroker(node_request["topic"], node_request["port"]);
300
- }
301
-
302
- if ("msg_type" in node_request) {
303
- topic_register[topic] = { "port": node_request["port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": node_request["msg_type"] }
304
- }
305
- else {
306
- topic_register[topic] = { "port": node_request["port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": "json" }
307
- }
308
-
309
- topic_register[topic]["nodes"] = [];
310
- }
311
-
312
- }
313
-
314
- var onNewTopic = function (node_request, topic_register) {
315
-
316
- // Asign new ports
317
- nep_configuration["current_port"] = nep_configuration["current_port"] + 2
318
- // Topic must be an string
319
- topic = String(node_request['topic'])
320
- var msg = {}
321
- // If publisher or subscriber
322
- if (node_request["socket"] === "publisher" || node_request["socket"] === "subscriber") {
323
- // Create new broker for many2many communication
324
- if (node_request["mode"] === "many2many") {
325
- createBroker(topic);
326
- msg = m2mResponse(node_request, topic_register, topic);
327
- }
328
- }
329
- else if (node_request["socket"] === "surveyor" || node_request["socket"] === "respondent") {
330
- msg = surveyResponse(node_request, topic_register, topic)
331
- }
332
- else if (node_request["socket"] === "client" || node_request["socket"] === "server") {
333
- msg = csResponse(node_request, topic_register, topic)
334
- }
335
- // Key for related nodes
336
- topic_register[topic]["nodes"] = {}
337
- // Set PID of node
338
- updatePID(node_request, topic_register, topic);
339
-
340
- if ("language" in node_request) {
341
-
342
- if (node_request["language"] == "C++") {
343
- msg.port = msg.port.toString();
344
- }
345
-
346
- }
347
-
348
- return msg
349
- }
350
-
351
-
352
-
353
- var createBroker = function (topic) {
354
- try {
355
- var broker = new Broker(nep_configuration["IP"], nep_configuration["current_port"] + 1, nep_configuration["current_port"])
356
- //var brokersubex = new BrokerBridgeSUBEX(conf["IP"],IP_EXTERNAL, conf["current_port"] , conf["current_port"])
357
-
358
- // Add broker defined to list of brokers
359
- nep_configuration["brokers"][topic] = broker
360
- } catch (error) {
361
- // console.log("NEP ERROR: ports " + String(nep_configuration["current_port"]) + " and " + String(nep_configuration["current_port"] + 1) + " not avaliable")
362
- nep_configuration["current_port"] = nep_configuration["current_port"] + 2
363
- var broker = new nep.Broker(nep_configuration["IP"], nep_configuration["current_port"] + 1, nep_configuration["current_port"])
364
- // Add broker defined to list of brokers
365
- nep_configuration["brokers"][topic] = broker
366
- }
367
- }
368
-
369
- var restartBroker = function (topic, port) {
370
- try {
371
- var broker = new nep.Broker(nep_configuration["IP"], port + 1, port)
372
- //var brokersubex = new BrokerBridgeSUBEX(conf["IP"],IP_EXTERNAL, conf["current_port"] , conf["current_port"])
373
- // Add broker defined to list of brokers
374
- nep_configuration["brokers"][topic] = broker
375
- } catch (error) {
376
- console.log("NEP ERROR: ports " + String(port) + " and " + String(port + 1) + " not avaliable")
377
- }
378
- }
379
-
380
- var m2mResponse = function (node_request, topic_register, topic) {
381
- if ("msg_type" in node_request) {
382
- topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": node_request["msg_type"] }
383
- }
384
- else {
385
- topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": "json" }
386
- }
387
- return { 'topic': topic, 'port': nep_configuration["current_port"], 'mode': node_request["mode"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
388
- }
389
-
390
- var surveyResponse = function (node_request, topic_register, topic) {
391
- topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"] }
392
- return { 'topic': topic, 'port': nep_configuration["current_port"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
393
- }
394
-
395
- var csResponse = function (node_request, topic_register, topic) {
396
- topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "msg_type": "json" }
397
- return { 'topic': topic, 'port': nep_configuration["current_port"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
398
- }
399
-
400
-
401
- var updatePID = function (node_request, topic_register, topic) {
402
- if ("pid" in node_request) {
403
- topic_register[topic]["nodes"][node_request['node']] = { 'socket': node_request["socket"], 'pid': node_request["pid"], 'ip': nep_configuration["IP"] }
404
- }
405
- else {
406
- topic_register[topic]["nodes"][node_request['node']] = { 'socket': node_request["socket"], 'pid': "n.a", 'ip': nep_configuration["IP"] }
407
- }
408
- }
409
-
410
-
411
- var restartTopics = function (node_request) {
412
- console.log(node_request)
413
- // Get topic name
414
- var topic = String(node_request['topic'])
415
-
416
- console.log(" --- Reset topic : *" + topic + "* ---")
417
- // Create new broker
418
- onResetTopic(node_request);
419
- onUpdateTopicList(topic_register)
420
- }
421
-
422
- var processMsg = function (json_msg, nodes_register, topic_register) {
423
-
424
- let node_request = JSON.parse(json_msg)
425
- console.log("NEP : Node request - node: " + node_request["node"] + ", socket: " + node_request["socket"] + ", topic: " + node_request["topic"])
426
-
427
- // Check node status
428
- if ('node' in node_request) {
429
-
430
- // Kill previous node with the same name
431
- if (node_request['node'] in nodes_register) {
432
-
433
- console.log("--- Node *" + node_request['node'] + "* already defined ---")
434
- var current_pid = nodes_register[node_request['node']]
435
- if (node_request['pid'] === current_pid) {
436
-
437
- }
438
- else {
439
- // TODO -- reset topics in node for graph
440
- console.log("Kill node: " + node_request['node'])
441
- nep.killNode(current_pid)
442
- }
443
- }
444
- else {
445
- console.log("--- New Node *" + node_request['node'] + "* ---")
446
- }
447
- }
448
-
449
- // Update node info
450
- nodes_register[node_request['node']] = node_request['pid']
451
- // Get topic name
452
- var topic = String(node_request['topic'])
453
- // Check topic status
454
- if (topic in topic_register) {
455
- console.log("--- Topic *" + topic + "* already registered --- ")
456
-
457
- // Send information of topic already defined
458
- var response = onRegisteredTopic(node_request, topic_register, topic)
459
- return JSON.stringify(response)
460
- }
461
- else {
462
- console.log(" --- New topic : *" + topic + "* ---")
463
- // Create new broker
464
- var response = onNewTopic(node_request, topic_register);
465
- return JSON.stringify(response)
466
- }
467
- }
468
-
469
- if (value1 === "wifi") {
470
-
471
- var ips = nep.getIP();
472
-
473
- if (ips.wifi === "") {
474
- console.log("NEP Error: No Wifi network detected")
475
- }
476
- else {
477
- console.log("NEP master in Wifi - " + ips.wifi);
478
- nep_configuration["IP"] = ips.wifi;
479
- var master = new MasterLocal(IP = ips.wifi);
480
- var info = new nep.MasterInfoServer(IP = ips.wifi, topics = topic_register);
481
- }
482
- }
483
- else if (value1 === "eth") {
484
-
485
- var ips = nep.getIP();
486
-
487
- if (ips.ethernet === "") {
488
- console.log("NEP Error: No ethernet network detected")
489
- }
490
- else {
491
- console.log("NEP master in Ethernet - " + ips.ethernet)
492
- nep_configuration["IP"] = ips.ethernet;
493
- var master = new MasterLocal(IP = ips.ethernet);
494
- var info = new nep.MasterInfoServer(IP = ips.ethernet, topics = topic_register);
495
- }
496
-
497
- }
498
- else if (value1 === "set") {
499
-
500
- console.log("NEP master in - " + value2)
501
- nep_configuration["IP"] = value2;
502
- var master = new MasterLocal(IP = value2);
503
- var info = new nep.MasterInfoServer(IP = value2, topics = topic_register);
504
-
505
- }
506
- //else if (value1 == "discover") {
507
- //var master = new MasterLocal();
508
- //console.log("NEP: Discover network ON")
509
- //getWifi();
510
- //getEthernet();
511
- //discoverable();
512
-
513
- //pub_params = node.new_pub("nep_network", "json");
514
-
515
- //var pubParams = function (msg) {
516
- // var params = { "wifi": devices, "ethernet": devices_ethernet }
517
- // pub_params.publish(params)
518
- //}
519
-
520
- //var paramTimer = setInterval(pubParams, 1000);
521
- //}
522
-
523
- else {
524
- var master = new MasterLocal();
525
- var info = new nep.MasterInfoServer(IP = '127.0.0.1', topics=topic_register);
526
-
527
- }
528
-
529
- }
530
- if (value == "ip") {
531
- var ips = nep.getIP();
532
- console.log("Wifi - " + ips.wifi);
533
- console.log("Ethernet - " + ips.ethernet)
534
- }
535
-
536
- if (value === "ipsend") {
537
-
538
- try {
539
- dicovery_send()
540
- } catch (error) {
541
- console.log("NEP: Error socket in use")
542
- }
543
- }
544
-
545
- if (value == "ipdiscover") {
546
- dicovery_server()
547
- }
548
-
549
-
550
- if (value === "topics") {
551
-
552
- var master_ip = "127.0.0.1";
553
- var ips = nep.getIP();
554
-
555
- if (value1 === undefined) {
556
- master_ip = "127.0.0.1";
557
- }
558
- else if (value1 === "wifi") {
559
- master_ip = ips.wifi;
560
- }
561
- else if (value1 === "eth") {
562
- master_ip = ips.ethernet;
563
- }
564
- else {
565
- master_ip = value1;
566
- }
567
-
568
- async function run() {
569
- var requester = new zmq.Request;
570
-
571
- requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
572
-
573
- let msg = { "input": "topics" }
574
- var message = JSON.stringify(msg);
575
- await requester.send(message)
576
- const [result] = await requester.receive()
577
- var results = JSON.parse(result.toString())
578
- //console.log(results);
579
- if (results["state"] === "failure") {
580
- console.log("No topics yet")
581
- }
582
- else {
583
- console.log("")
584
-
585
- results["input"].forEach(element => {
586
- console.log(element)
587
- });
588
- }
589
-
590
-
591
- }
592
-
593
- run()
594
-
595
- }
596
-
597
- if (value === "help") {
598
-
599
- var help = `
600
- master - master in local host
601
- master wifi - master in current wifi network
602
- master eth - master in ethernet network
603
- master set <ip> - master in <ip>
604
-
605
- topics - print list of topics registered in localhost
606
- topics wifi - print list of topics registered in wifi
607
- topics eth - print list of topics registered in ethernet
608
- topics <ip> - print list of topics registered in <ip>
609
-
610
- publish <topic> <msg> - publish <msg> in <topic> in localhost
611
- publish <topic> wifi <msg> - publish <msg> in <topic> in wifi network
612
- publish <topic> eth <msg> - publish <msg> in <topic> in ethernet network
613
- publish <topic> <ip> <msg> - publish <msg> in <topic> in <ip>
614
-
615
- listen <topic> - subscribe to <topic> and print results in json
616
- listen <topic> wifi - subscribe to <topic> in wifi network
617
- listen <topic> eth - subscribe to <topic> in ethernet network
618
- listen <topic> <ip> - subscribe to <topic> in <ip>
619
-
620
- listen-t <topic> - subscribe to <topic> and print as a table
621
- listen-t <topic> wifi - subscribe to <topic> in wifi network
622
- listen-t <topic> eth - subscribe to <topic> in ethernet network
623
- listen-t <topic> <ip> - subscribe to <topic> in <ip>
624
-
625
- ip - see current ip for wifi and ethernet
626
-
627
- `;
628
- console.log(help)
629
-
630
- }
631
-
632
- if (value === "publish" || value === "pub") {
633
-
634
-
635
- var openpub = function (master_ip = "127.0.0.1") {
636
-
637
- var pubFunction = function () {
638
-
639
- var msg = value2.replace(/'/g, '"')
640
- console.log(JSON.parse(msg))
641
- pub.publish(JSON.parse(msg))
642
- console.log("message published")
643
-
644
- process.exit(1)
645
- }
646
-
647
-
648
- var node = new nep.Node("nep-cli-pub")
649
- var pub = node.new_pub(value1, "json")
650
- setTimeout(pubFunction, 1000)
651
- }
652
-
653
- var master_ip = "127.0.0.1";
654
- var ips = nep.getIP();
655
-
656
- if (value3 === undefined) {
657
- master_ip = "127.0.0.1";
658
- }
659
- else if (value3 === "wifi") {
660
- master_ip = ips.wifi;
661
- }
662
- else if (value3 === "eth") {
663
- master_ip = ips.ethernet;
664
- }
665
- else {
666
- master_ip = value3;
667
- }
668
-
669
- async function run() {
670
- var requester = new zmq.Request;
671
-
672
- requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
673
-
674
- let msg = { "input": "topics" }
675
- var message = JSON.stringify(msg);
676
- await requester.send(message)
677
- const [result] = await requester.receive()
678
- var results = JSON.parse(result.toString())
679
- //console.log(results);
680
- if (results["state"] === "failure") {
681
- console.log("Topic is not registered");
682
- }
683
- else {
684
- console.log("")
685
-
686
- if (results["input"].includes(value1)) {
687
- openpub(master_ip);
688
- }
689
- else {
690
- console.log("Topic is not registered")
691
- }
692
- }
693
-
694
-
695
- }
696
-
697
- run()
698
-
699
-
700
- }
701
-
702
- if (value === "listen" || value === "listen-t") {
703
-
704
-
705
- var opensub = function (master_ip = "127.0.0.1") {
706
- var callback = function (msg) {
707
- var date = new Date();
708
- var dateString = date.toISOString();
709
- console.log(dateString);
710
-
711
- if (msg.length > 10000) {
712
- console.log("the message is so long to be displayed")
713
- }
714
- else {
715
-
716
-
717
- if (value == "listen") {
718
- console.log(JSON.stringify(msg, null, 4));
719
- }
720
- else {
721
-
722
- console.log(msg)
723
- console.table(msg);
724
- }
725
-
726
-
727
-
728
- }
729
-
730
- }
731
-
732
- var node = new nep.Node("nep-cli-sub");
733
- var conf = node.hybrid(master_ip)
734
- sub = node.new_sub(value1, "json", callback, conf)
735
- }
736
-
737
- var master_ip = "127.0.0.1";
738
- var ips = nep.getIP();
739
-
740
- if (value2 === undefined) {
741
- master_ip = "127.0.0.1";
742
- }
743
- else if (value2 === "wifi") {
744
- master_ip = ips.wifi;
745
- }
746
- else if (value2 === "eth") {
747
- master_ip = ips.ethernet;
748
- }
749
- else {
750
- master_ip = value2;
751
- }
752
-
753
- async function run() {
754
- var requester = new zmq.Request;
755
-
756
- requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
757
-
758
- let msg = { "input": "topics" }
759
- var message = JSON.stringify(msg);
760
- await requester.send(message)
761
- const [result] = await requester.receive()
762
- var results = JSON.parse(result.toString())
763
- //console.log(results);
764
- if (results["state"] === "failure") {
765
- console.log("Topic is not registered");
766
- }
767
- else {
768
- console.log("")
769
-
770
- if (results["input"].includes(value1)) {
771
- opensub(master_ip);
772
- }
773
- else {
774
- console.log("Topic is not registered")
775
- }
776
- }
777
-
778
-
779
- }
780
-
781
- run()
782
-
783
-
784
-
785
-
786
- }
787
-
788
-
789
- if (value === "init") {
790
-
791
- }
792
-
793
-
794
- if (value === "bridge") {
795
-
796
- var pathNEP = 'C:/nep'
797
-
798
- if (opsys == "darwin") {
799
- opsys = "MacOS";
800
- pathNEP = require("os").userInfo.homedir
801
- } else if (opsys === "win32" || opsys === "win64") {
802
- opsys = "Windows";
803
- pathNEP = 'C:/nep'
804
- } else if (opsys == "linux") {
805
- opsys = "Linux";
806
- pathNEP = process.env.HOME + '/Documents/nep'
807
- }
808
-
809
- const { spawn } = require('child_process');
810
- var opsys = process.platform;
811
-
812
-
813
- var args = pathNEP + "/bridge.py"
814
-
815
- robot_process = spawn('python', [args]);
816
-
817
-
818
- robot_process.stdout.on('data', (data) => {
819
- console.log("--------ROBOT -----")
820
- console.log(`stdout: ${data}`);
821
- });
822
-
823
- robot_process.stderr.on('data', (data) => {
824
- console.log("--------ROBOT -----")
825
- console.error(`stderr: ${data}`);
826
- });
827
-
828
- robot_process.on('close', (code) => {
829
- console.log(`child process exited with code ${code}`);
830
- });
831
-
832
-
833
-
834
- }
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const os = require('os');
5
+ const zmq = require("zeromq");
6
+ var nep = require('nep-js');
7
+ var nep_configuration = { current_port: 10000, IP: "127.0.0.1", brokers: {} }
8
+ const { exec } = require('child_process');
9
+ const { AutoComplete } = require('enquirer');
10
+
11
+
12
+ // Node saved here
13
+ var nodes_register = {};
14
+ // ----------- Main variables ---------------
15
+ // Topics saved here
16
+ var topic_register = {};
17
+
18
+ class MasterLocal {
19
+ constructor(IP = '127.0.0.1', port_ = 7000) {
20
+ this.port = String(port_)
21
+ var address = "tcp://" + IP + ":" + this.port
22
+ console.log("New Master in: " + address)
23
+ try {
24
+ async function run() {
25
+ const reply = new zmq.Reply
26
+ await reply.bind(address)
27
+ for await (const [node_request] of reply) {
28
+ await reply.send(processMsg(node_request, nodes_register, topic_register))
29
+ }
30
+ }
31
+ run()
32
+ } catch (error) {
33
+ }
34
+ }
35
+ }
36
+
37
+ var onRegisteredTopic = function (node_request, topic_register, topic) {
38
+
39
+ var msg = { "state": "failure" }
40
+
41
+ try {
42
+ var port = topic_register[topic]["port"]
43
+ var socket_ = topic_register[topic]["socket"]
44
+
45
+ if ("mode" in topic_register[topic]) {
46
+ var mode = topic_register[topic]["mode"]
47
+ msg = { 'topic': topic, 'port': port, 'mode': mode, 'ip': nep_configuration["IP"], 'socket': socket_, "state": "success" }
48
+ }
49
+ else {
50
+ msg = { 'topic': topic, 'port': port, 'ip': nep_configuration["IP"], 'socket': socket_, "state": "success" }
51
+ }
52
+ updatePID(node_request, topic_register, topic)
53
+
54
+ } catch (error) {
55
+ console.log("Error in topic request")
56
+ }
57
+
58
+ if ("language" in node_request) {
59
+
60
+ if (node_request["language"] == "C++") {
61
+ msg.port = msg.port.toString();
62
+ }
63
+
64
+ }
65
+
66
+ return msg
67
+ }
68
+
69
+
70
+ var onResetTopic = function (node_request) {
71
+
72
+ var topic = node_request["topic"]
73
+ nep_configuration["current_port"] = Math.max(nep_configuration["current_port"], node_request["port"] + 2);
74
+
75
+ if (node_request["socket"] === "publisher" || node_request["socket"] === "subscriber") {
76
+ // Create new broker for many2many communication
77
+ if (node_request["mode"] === "many2many") {
78
+ restartBroker(node_request["topic"], node_request["port"]);
79
+ }
80
+
81
+ if ("msg_type" in node_request) {
82
+ topic_register[topic] = { "port": node_request["port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": node_request["msg_type"] }
83
+ }
84
+ else {
85
+ topic_register[topic] = { "port": node_request["port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": "json" }
86
+ }
87
+
88
+ topic_register[topic]["nodes"] = [];
89
+ }
90
+
91
+ }
92
+
93
+ var onNewTopic = function (node_request, topic_register) {
94
+
95
+ // Asign new ports
96
+ nep_configuration["current_port"] = nep_configuration["current_port"] + 2
97
+ // Topic must be an string
98
+ topic = String(node_request['topic'])
99
+ var msg = {}
100
+ // If publisher or subscriber
101
+ if (node_request["socket"] === "publisher" || node_request["socket"] === "subscriber") {
102
+ // Create new broker for many2many communication
103
+ if (node_request["mode"] === "many2many") {
104
+ createBroker(topic);
105
+ msg = m2mResponse(node_request, topic_register, topic);
106
+ }
107
+ }
108
+ else if (node_request["socket"] === "surveyor" || node_request["socket"] === "respondent") {
109
+ msg = surveyResponse(node_request, topic_register, topic)
110
+ }
111
+ else if (node_request["socket"] === "client" || node_request["socket"] === "server") {
112
+ msg = csResponse(node_request, topic_register, topic)
113
+ }
114
+ // Key for related nodes
115
+ topic_register[topic]["nodes"] = {}
116
+ // Set PID of node
117
+ updatePID(node_request, topic_register, topic);
118
+
119
+ if ("language" in node_request) {
120
+
121
+ if (node_request["language"] == "C++") {
122
+ msg.port = msg.port.toString();
123
+ }
124
+
125
+ }
126
+
127
+ return msg
128
+ }
129
+
130
+
131
+
132
+ var createBroker = function (topic) {
133
+ try {
134
+ var broker = new Broker(nep_configuration["IP"], nep_configuration["current_port"] + 1, nep_configuration["current_port"])
135
+ //var brokersubex = new BrokerBridgeSUBEX(conf["IP"],IP_EXTERNAL, conf["current_port"] , conf["current_port"])
136
+
137
+ // Add broker defined to list of brokers
138
+ nep_configuration["brokers"][topic] = broker
139
+ } catch (error) {
140
+ // console.log("NEP ERROR: ports " + String(nep_configuration["current_port"]) + " and " + String(nep_configuration["current_port"] + 1) + " not avaliable")
141
+ nep_configuration["current_port"] = nep_configuration["current_port"] + 2
142
+ var broker = new nep.Broker(nep_configuration["IP"], nep_configuration["current_port"] + 1, nep_configuration["current_port"])
143
+ // Add broker defined to list of brokers
144
+ nep_configuration["brokers"][topic] = broker
145
+ }
146
+ }
147
+
148
+ var restartBroker = function (topic, port) {
149
+ try {
150
+ var broker = new nep.Broker(nep_configuration["IP"], port + 1, port)
151
+ //var brokersubex = new BrokerBridgeSUBEX(conf["IP"],IP_EXTERNAL, conf["current_port"] , conf["current_port"])
152
+ // Add broker defined to list of brokers
153
+ nep_configuration["brokers"][topic] = broker
154
+ } catch (error) {
155
+ console.log("NEP ERROR: ports " + String(port) + " and " + String(port + 1) + " not avaliable")
156
+ }
157
+ }
158
+
159
+ var m2mResponse = function (node_request, topic_register, topic) {
160
+ if ("msg_type" in node_request) {
161
+ topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": node_request["msg_type"] }
162
+ }
163
+ else {
164
+ topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "mode": node_request["mode"], "msg_type": "json" }
165
+ }
166
+ return { 'topic': topic, 'port': nep_configuration["current_port"], 'mode': node_request["mode"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
167
+ }
168
+
169
+ var surveyResponse = function (node_request, topic_register, topic) {
170
+ topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"] }
171
+ return { 'topic': topic, 'port': nep_configuration["current_port"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
172
+ }
173
+
174
+ var csResponse = function (node_request, topic_register, topic) {
175
+ topic_register[topic] = { "port": nep_configuration["current_port"], "socket": node_request["socket"], 'ip': nep_configuration["IP"], "msg_type": "json" }
176
+ return { 'topic': topic, 'port': nep_configuration["current_port"], 'ip': nep_configuration["IP"], 'socket': node_request["socket"], "state": "success" }
177
+ }
178
+
179
+
180
+ var updatePID = function (node_request, topic_register, topic) {
181
+ if ("pid" in node_request) {
182
+ topic_register[topic]["nodes"][node_request['node']] = { 'socket': node_request["socket"], 'pid': node_request["pid"], 'ip': nep_configuration["IP"] }
183
+ }
184
+ else {
185
+ topic_register[topic]["nodes"][node_request['node']] = { 'socket': node_request["socket"], 'pid': "n.a", 'ip': nep_configuration["IP"] }
186
+ }
187
+ }
188
+
189
+
190
+ var restartTopics = function (node_request) {
191
+ console.log(node_request)
192
+ // Get topic name
193
+ var topic = String(node_request['topic'])
194
+
195
+ console.log(" --- Reset topic : *" + topic + "* ---")
196
+ // Create new broker
197
+ onResetTopic(node_request);
198
+ onUpdateTopicList(topic_register)
199
+ }
200
+
201
+ var processMsg = function (json_msg, nodes_register, topic_register) {
202
+
203
+ let node_request = JSON.parse(json_msg)
204
+ console.log("NEP : Node request - node: " + node_request["node"] + ", socket: " + node_request["socket"] + ", topic: " + node_request["topic"])
205
+
206
+ // Check node status
207
+ if ('node' in node_request) {
208
+
209
+ // Kill previous node with the same name
210
+ if (node_request['node'] in nodes_register) {
211
+
212
+ console.log("--- Node *" + node_request['node'] + "* already defined ---")
213
+ var current_pid = nodes_register[node_request['node']]
214
+ if (node_request['pid'] === current_pid) {
215
+
216
+ }
217
+ else {
218
+ // TODO -- reset topics in node for graph
219
+ console.log("Kill node: " + node_request['node'])
220
+ nep.killNode(current_pid)
221
+ }
222
+ }
223
+ else {
224
+ console.log("--- New Node *" + node_request['node'] + "* ---")
225
+ }
226
+ }
227
+
228
+ // Update node info
229
+ nodes_register[node_request['node']] = node_request['pid']
230
+ // Get topic name
231
+ var topic = String(node_request['topic'])
232
+ // Check topic status
233
+ if (topic in topic_register) {
234
+ console.log("--- Topic *" + topic + "* already registered --- ")
235
+
236
+ // Send information of topic already defined
237
+ var response = onRegisteredTopic(node_request, topic_register, topic)
238
+ return JSON.stringify(response)
239
+ }
240
+ else {
241
+ console.log(" --- New topic : *" + topic + "* ---")
242
+ // Create new broker
243
+ var response = onNewTopic(node_request, topic_register);
244
+ return JSON.stringify(response)
245
+ }
246
+ }
247
+
248
+ const PORT_MASTER_INFO = 7010; // Default port for master info
249
+
250
+ program
251
+ .version('"0.1.2')
252
+ .description('NEP+ CLI');
253
+
254
+ program
255
+ .command('ip')
256
+ .description('Display current Wi-Fi and Ethernet IP addresses')
257
+ .action(() => {
258
+ const interfaces = os.networkInterfaces();
259
+
260
+ // Find Wi-Fi interface
261
+ const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
262
+ if (wifiInterface) {
263
+ const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
264
+ if (wifiIPv4) {
265
+ console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
266
+ } else {
267
+ console.log('No Wi-Fi IPv4 address found.');
268
+ }
269
+ } else {
270
+ console.log('Wi-Fi interface not found.');
271
+ }
272
+
273
+ // Find Ethernet interface
274
+ const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
275
+ if (ethernetInterface) {
276
+ const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
277
+ if (ethernetIPv4) {
278
+ console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
279
+ } else {
280
+ console.log('No Ethernet IPv4 address found.');
281
+ }
282
+ } else {
283
+ console.log('Ethernet interface not found.');
284
+ }
285
+ });
286
+
287
+ program
288
+ .command('app')
289
+ .description('Open NEP+ App')
290
+ .action(() => {
291
+ // Get the username of the logged-in user
292
+ const username = os.userInfo().username;
293
+
294
+ // Specify the path to the executable
295
+ const appFolderName = 'nepplus';
296
+ const executableName = 'Nep+ App.exe';
297
+ const executablePath = `C:\\Users\\${username}\\AppData\\Local\\Programs\\${appFolderName}\\${executableName}`;
298
+
299
+ // Run the executable with proper escaping
300
+ exec(`"${executablePath}"`, (error, stdout, stderr) => {
301
+ if (error) {
302
+ console.error(`Error: ${error.message}`);
303
+ return;
304
+ }
305
+ console.log(`stdout: ${stdout}`);
306
+ console.error(`stderr: ${stderr}`);
307
+ });
308
+ });
309
+
310
+
311
+ program
312
+ .command('open [programName]')
313
+ .description('Open a program in Windows/macOS')
314
+ .action(async (programName) => {
315
+ const programs = ['camera-js', 'hxri', 'rize', 'sharo'];
316
+
317
+ // If a program name is provided as an argument, use it; otherwise, show autocomplete
318
+ if (!programName) {
319
+ const autoComplete = new AutoComplete({
320
+ name: 'program',
321
+ message: 'Select a program:',
322
+ choices: programs,
323
+ });
324
+ programName = await autoComplete.run();
325
+ } else if (!programs.includes(programName)) {
326
+ const autoComplete = new AutoComplete({
327
+ name: 'program',
328
+ message: 'Invalid program name. Select a valid program:',
329
+ choices: programs,
330
+ });
331
+ programName = await autoComplete.run();
332
+ }
333
+
334
+ // Get the username of the logged-in user
335
+ const username = os.userInfo().username;
336
+
337
+ // Specify the path to the executable
338
+ const appFolderName = 'nepplus' + "-" + programName;
339
+ const executableName = 'nepplus' + "-" + `${programName}.exe`;
340
+ const executablePath = `C:\\Users\\${username}\\AppData\\Local\\Programs\\${appFolderName}\\${executableName}`;
341
+
342
+ // Run the executable with proper escaping
343
+ exec(`"${executablePath}"`, (error, stdout, stderr) => {
344
+ if (error) {
345
+ console.error(`Error: ${error.message}`);
346
+ return;
347
+ }
348
+ console.log(`stdout: ${stdout}`);
349
+ console.error(`stderr: ${stderr}`);
350
+ });
351
+ });
352
+
353
+ program
354
+ .command('master')
355
+ .description('Start NEP master in Local host')
356
+ .action(async () => {
357
+ try {
358
+ var node = new nep.Node("nep-cli");
359
+ console.log("Starting NEP master in terminal")
360
+ var master = new MasterLocal();
361
+ var info = new nep.MasterInfoServer(IP = '127.0.0.1', topics = topic_register);
362
+ } catch (error) {
363
+ if (error.message.includes('EADDRINUSE')) {
364
+ console.error("Error: Address already in use. Another instance of NEP master might be running.");
365
+ } else {
366
+ console.error("An error occurred:", error.message);
367
+ }
368
+ }
369
+ });
370
+
371
+ program
372
+ .command('master-ip <ip>' )
373
+ .description('Start NEP master in some specific IP')
374
+ .action(async (ip) => {
375
+
376
+
377
+ console.log(`IP Address: ${ip}`);
378
+ var node = new nep.Node("nep-cli");
379
+ nep_configuration["IP"] = ip;
380
+ var master = new MasterLocal(IP = ip);
381
+ var info = new nep.MasterInfoServer(IP = ip, topics = topic_register);
382
+
383
+ });
384
+
385
+
386
+ program
387
+ .command('eth')
388
+ .description('Start NEP master in Ethernet network')
389
+ .action(async () => {
390
+
391
+ const interfaces = os.networkInterfaces();
392
+
393
+ const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
394
+ if (ethernetInterface) {
395
+ const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
396
+ if (ethernetIPv4) {
397
+ console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
398
+ var node = new nep.Node("nep-cli");
399
+ nep_configuration["IP"] = ethernetIPv4.address;
400
+ var master = new MasterLocal(IP = ethernetIPv4.address);
401
+ var info = new nep.MasterInfoServer(IP = ethernetIPv4.address, topics = topic_register);
402
+ } else {
403
+ console.log('No Ethernet IPv4 address found.');
404
+ }
405
+ } else {
406
+ console.log('Ethernet interface not found.');
407
+ }
408
+ });
409
+
410
+
411
+ program
412
+ .command('wifi')
413
+ .description('Start NEP master in Wi-Fi network')
414
+ .action(async () => {
415
+
416
+ const interfaces = os.networkInterfaces();
417
+
418
+ // Find Wi-Fi interface
419
+ const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
420
+ if (wifiInterface) {
421
+ const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
422
+ if (wifiIPv4) {
423
+ console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
424
+ try {
425
+ var node = new nep.Node("nep-cli");
426
+ nep_configuration["IP"] = wifiIPv4.address;
427
+ var master = new MasterLocal(IP = wifiIPv4.address);
428
+ var info = new nep.MasterInfoServer(IP = wifiIPv4.address, topics = topic_register);
429
+ } catch (error) {
430
+ if (error.message.includes('EADDRINUSE')) {
431
+ console.error("Error: Address already in use. Another instance of NEP master might be running.");
432
+ } else {
433
+ console.error("An error occurred:", error.message);
434
+ }
435
+ }
436
+
437
+ } else {
438
+ console.log('No Wi-Fi IPv4 address found.');
439
+ }
440
+ } else {
441
+ console.log('Wi-Fi interface not found.');
442
+ }
443
+ });
444
+
445
+ program
446
+ .command('topics')
447
+ .description('Get list of NEP+ topics')
448
+ .action(async () => {
449
+ const master_ip = "127.0.0.1";
450
+ const TIMEOUT_DURATION = 5000; // Timeout duration in milliseconds
451
+
452
+ async function getTopics() {
453
+ var requester = new zmq.Request();
454
+ requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
455
+
456
+ let msg = { "input": "topics" };
457
+ var message = JSON.stringify(msg);
458
+
459
+ try {
460
+ // Create a Promise that resolves when a response is received
461
+ const responsePromise = new Promise(async (resolve, reject) => {
462
+ await requester.send(message);
463
+ const [result] = await requester.receive();
464
+ var results = JSON.parse(result.toString());
465
+ resolve(results);
466
+ });
467
+
468
+ // Create a Promise that rejects after the specified timeout
469
+ const timeoutPromise = new Promise((resolve, reject) => {
470
+ setTimeout(() => {
471
+ reject(new Error("Timed out, NEP master in local-host was not found"));
472
+ }, TIMEOUT_DURATION);
473
+ });
474
+
475
+ // Use Promise.race to wait for either the response or the timeout
476
+ const results = await Promise.race([responsePromise, timeoutPromise]);
477
+
478
+ if (results["state"] === "success") {
479
+ availableTopics = results["input"]; // Store the topics here
480
+ console.log("");
481
+ results["input"].forEach(element => {
482
+ console.log(element);
483
+ });
484
+ } else {
485
+ console.log("No topics yet");
486
+ }
487
+ } catch (error) {
488
+ console.error("Error:", error.message);
489
+ } finally {
490
+ // Detach the requester socket from its context
491
+ process.exit();
492
+ }
493
+ }
494
+
495
+ await getTopics(); // Call the function to get topics
496
+ });
497
+
498
+ program
499
+ .command('eth-topics')
500
+ .description('Get list of NEP+ topics over Ethernet')
501
+ .action(async () => {
502
+ const interfaces = os.networkInterfaces();
503
+ const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
504
+
505
+ if (ethernetInterface) {
506
+ const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
507
+ if (ethernetIPv4) {
508
+ const master_ip = ethernetIPv4.address;
509
+ console.log('Asking to NEP+ master in -', ethernetIPv4.address);
510
+ console.log("\n")
511
+ await getAndDisplayTopics(master_ip);
512
+ } else {
513
+ console.log('No Ethernet IPv4 address found.');
514
+ }
515
+ } else {
516
+ console.log('Ethernet interface not found.');
517
+ }
518
+ });
519
+
520
+
521
+ program
522
+ .command('wifi-topics')
523
+ .description('Get list of NEP+ topics over Wi-Fi')
524
+ .action(async () => {
525
+ const interfaces = os.networkInterfaces();
526
+ const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
527
+
528
+ if (wifiInterface) {
529
+ const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
530
+ if (wifiIPv4) {
531
+ const master_ip = wifiIPv4.address; // Set the Wi-Fi IP address dynamically
532
+ console.log('Asking to NEP+ master in -', wifiIPv4.address);
533
+ console.log("\n")
534
+ const TIMEOUT_DURATION = 5000;
535
+
536
+ async function getTopics() {
537
+ var requester = new zmq.Request();
538
+ requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
539
+
540
+ let msg = { "input": "topics" };
541
+ var message = JSON.stringify(msg);
542
+
543
+ try {
544
+ const responsePromise = new Promise(async (resolve, reject) => {
545
+ await requester.send(message);
546
+ const [result] = await requester.receive();
547
+ var results = JSON.parse(result.toString());
548
+ resolve(results);
549
+ });
550
+
551
+ const timeoutPromise = new Promise((resolve, reject) => {
552
+ setTimeout(() => {
553
+ reject(new Error("Timed out, NEP master over Wi-Fi was not found"));
554
+ }, TIMEOUT_DURATION);
555
+ });
556
+
557
+ const results = await Promise.race([responsePromise, timeoutPromise]);
558
+
559
+ if (results["state"] === "success") {
560
+ availableTopics = results["input"]; // Store the topics here
561
+ console.log("");
562
+ results["input"].forEach(element => {
563
+ console.log(element);
564
+ });
565
+ } else {
566
+ console.log("No topics yet");
567
+ }
568
+ } catch (error) {
569
+ console.error("Error:", error.message);
570
+ } finally {
571
+ process.exit();
572
+ }
573
+ }
574
+
575
+ await getTopics();
576
+
577
+ } else {
578
+ console.log('No Wi-Fi IPv4 address found.');
579
+ }
580
+ } else {
581
+ console.log('Wi-Fi interface not found.');
582
+ }
583
+ });
584
+
585
+
586
+ program
587
+ .command('publish <topic> <message>')
588
+ .description('Publish a message to a NEP+ topic')
589
+ .action((topic, message) => {
590
+
591
+ var openpub = function (master_ip = "127.0.0.1") {
592
+
593
+ var pubFunction = function () {
594
+
595
+ var msg = message.replace(/'/g, '"')
596
+ console.log(JSON.parse(msg))
597
+ pub.publish(JSON.parse(msg))
598
+ console.log("Message published")
599
+
600
+ process.exit(1)
601
+ }
602
+
603
+
604
+ var node = new nep.Node("nep-cli-pub")
605
+ var pub = node.new_pub(topic, "json")
606
+ setTimeout(pubFunction, 1000)
607
+ }
608
+
609
+ async function run() {
610
+ var requester = new zmq.Request;
611
+ var master_ip = "127.0.0.1"
612
+
613
+ requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
614
+
615
+ let msg = { "input": "topics" }
616
+ var message = JSON.stringify(msg);
617
+ await requester.send(message)
618
+ const [result] = await requester.receive()
619
+ var results = JSON.parse(result.toString())
620
+ //console.log(results);
621
+ if (results["input"].includes(topic)) {
622
+ console.log("")
623
+ openpub(master_ip)
624
+ }
625
+ else {
626
+ console.log("Topic is not registered");
627
+ }
628
+ }
629
+ run()
630
+ });
631
+
632
+
633
+
634
+ program
635
+ .command('eth-publish <topic> <message>')
636
+ .description('Publish a message to a NEP+ topic over Ethernet')
637
+ .action((topic, message) => {
638
+
639
+ const interfaces = os.networkInterfaces();
640
+
641
+ var openpub = function (master_ip = "127.0.0.1") {
642
+
643
+ var pubFunction = function () {
644
+
645
+ var msg = message.replace(/'/g, '"')
646
+ console.log(JSON.parse(msg))
647
+ pub.publish(JSON.parse(msg))
648
+ console.log("Message published")
649
+
650
+ process.exit(1)
651
+ }
652
+
653
+
654
+ var node = new nep.Node("nep-cli-pub")
655
+ var pub = node.new_pub(topic, "json")
656
+ setTimeout(pubFunction, 1000)
657
+ }
658
+
659
+ async function run(master_ip) {
660
+ var requester = new zmq.Request();
661
+ requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
662
+
663
+ let msg = { "input": "topics" };
664
+ var message = JSON.stringify(msg);
665
+
666
+
667
+ try {
668
+ await requester.send(message);
669
+ const [result] = await Promise.race([requester.receive(), timeoutPromise(5000)]); // Timeout of 5 seconds
670
+ var results = JSON.parse(result.toString());
671
+
672
+ if (results["input"].includes(topic)) {
673
+ console.log("");
674
+ openpub(master_ip);
675
+ } else {
676
+ console.log("Topic is not registered");
677
+ }
678
+ } catch (error) {
679
+ console.error("Error:", error.message);
680
+ } finally {
681
+ process.exit(1)
682
+ }
683
+ }
684
+
685
+ const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
686
+ if (ethernetInterface) {
687
+ const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
688
+ if (ethernetIPv4) {
689
+ console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
690
+ run(ethernetIPv4.address)
691
+ } else {
692
+ console.log('No Ethernet IPv4 address found.');
693
+ }
694
+ } else {
695
+ console.log('Ethernet interface not found.');
696
+ }
697
+ });
698
+
699
+ program
700
+ .command('wifi-publish <topic> <message>')
701
+ .description('Publish a message to a NEP+ topic over Wi-Fi')
702
+ .action((topic, message) => {
703
+
704
+ const interfaces = os.networkInterfaces();
705
+
706
+ var openpub = function (master_ip = "127.0.0.1") {
707
+
708
+ var pubFunction = function () {
709
+
710
+ var msg = message.replace(/'/g, '"')
711
+ console.log(JSON.parse(msg))
712
+ pub.publish(JSON.parse(msg))
713
+ console.log("Message published")
714
+
715
+ process.exit(1)
716
+ }
717
+
718
+
719
+ var node = new nep.Node("nep-cli-pub")
720
+ var pub = node.new_pub(topic, "json")
721
+ setTimeout(pubFunction, 1000)
722
+ }
723
+
724
+ async function run(master_ip) {
725
+ var requester = new zmq.Request();
726
+ requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
727
+
728
+ let msg = { "input": "topics" };
729
+ var message = JSON.stringify(msg);
730
+
731
+
732
+ try {
733
+ await requester.send(message);
734
+ const [result] = await Promise.race([requester.receive(), timeoutPromise(5000)]); // Timeout of 5 seconds
735
+ var results = JSON.parse(result.toString());
736
+
737
+ if (results["input"].includes(topic)) {
738
+ console.log("");
739
+ openpub(master_ip);
740
+ } else {
741
+ console.log("Topic is not registered");
742
+ }
743
+ } catch (error) {
744
+ console.error("Error:", error.message);
745
+ } finally {
746
+ process.exit(1)
747
+ }
748
+ }
749
+ const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
750
+ if (wifiInterface) {
751
+ const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
752
+ if (wifiIPv4) {
753
+ console.log(`Wi-Fi IP Address: ${wifiIPv4.address}`);
754
+ run(wifiIPv4.address)
755
+ } else {
756
+ console.log('No Wi-Fi IPv4 address found.');
757
+ }
758
+ } else {
759
+ console.log('Wi-Fi interface not found.');
760
+ }
761
+ });
762
+
763
+
764
+ program
765
+ .command('listen <topic>')
766
+ .description('Listen to a NEP+ topic')
767
+ .action(async (topic) => {
768
+ const interfaces = os.networkInterfaces();
769
+
770
+ var opensub = function (master_ip = "127.0.0.1") {
771
+ var callback = function (msg) {
772
+ var date = new Date();
773
+ var dateString = date.toISOString();
774
+ console.log(dateString);
775
+
776
+ if (msg.length > 10000) {
777
+ console.log("the message is too long to be displayed");
778
+ } else {
779
+ console.log(msg);
780
+ }
781
+ };
782
+
783
+ var node = new nep.Node("nep-cli-sub");
784
+ var conf = node.hybrid(master_ip);
785
+ sub = node.new_sub(topic, "json", callback, conf);
786
+ };
787
+
788
+ var master_ip = "127.0.0.1";
789
+ async function run() {
790
+ var requester = new zmq.Request();
791
+ requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
792
+
793
+ let msg = { "input": "topics" };
794
+ var message = JSON.stringify(msg);
795
+ await requester.send(message);
796
+ const [result] = await requester.receive();
797
+ var results = JSON.parse(result.toString());
798
+
799
+ if (results["state"] === "failure") {
800
+ console.log("Topic is not registered");
801
+ } else {
802
+ console.log("");
803
+ if (results["input"].includes(topic)) {
804
+ opensub(master_ip);
805
+ } else {
806
+ console.log("Topic is not registered");
807
+ }
808
+ }
809
+ }
810
+
811
+ run();
812
+ });
813
+
814
+ program
815
+ .command('eth-listen <topic>')
816
+ .description('Listen to a NEP+ topic')
817
+ .action(async (topic) => {
818
+ const interfaces = os.networkInterfaces();
819
+
820
+ var opensub = function (master_ip = "127.0.0.1") {
821
+ var callback = function (msg) {
822
+ var date = new Date();
823
+ var dateString = date.toISOString();
824
+ console.log(dateString);
825
+
826
+ if (msg.length > 10000) {
827
+ console.log("the message is too long to be displayed");
828
+ } else {
829
+ console.log(msg);
830
+ }
831
+ };
832
+
833
+ var node = new nep.Node("nep-cli-sub");
834
+ var conf = node.hybrid(master_ip);
835
+ sub = node.new_sub(topic, "json", callback, conf);
836
+ };
837
+
838
+ async function run(master_ip) {
839
+ var requester = new zmq.Request();
840
+ requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
841
+
842
+ let msg = { "input": "topics" };
843
+ var message = JSON.stringify(msg);
844
+ await requester.send(message);
845
+ const [result] = await requester.receive();
846
+ var results = JSON.parse(result.toString());
847
+
848
+ if (results["state"] === "failure") {
849
+ console.log("Topic is not registered");
850
+ } else {
851
+ console.log("");
852
+ if (results["input"].includes(topic)) {
853
+ opensub(master_ip);
854
+ } else {
855
+ console.log("Topic is not registered");
856
+ }
857
+ }
858
+ }
859
+
860
+ // Find Ethernet interface
861
+ const ethernetInterface = interfaces['Ethernet'] || interfaces['Ethernet 2'] || interfaces['eth0'] || interfaces['イーサネット'] || interfaces['enp0s10'];
862
+ if (ethernetInterface) {
863
+ const ethernetIPv4 = ethernetInterface.find(iface => iface.family === 'IPv4');
864
+ if (ethernetIPv4) {
865
+ console.log(`Ethernet IP Address: ${ethernetIPv4.address}`);
866
+ run(ethernetIPv4.address)
867
+ } else {
868
+ console.log('No Ethernet IPv4 address found.');
869
+ }
870
+ } else {
871
+ console.log('Ethernet interface not found.');
872
+ }
873
+ });
874
+
875
+ program
876
+ .command('wifi-listen <topic>')
877
+ .description('Listen to a NEP+ topic')
878
+ .action(async (topic) => {
879
+ const interfaces = os.networkInterfaces();
880
+
881
+ var opensub = function (master_ip = "127.0.0.1") {
882
+ var callback = function (msg) {
883
+ var date = new Date();
884
+ var dateString = date.toISOString();
885
+ console.log(dateString);
886
+
887
+ if (msg.length > 10000) {
888
+ console.log("the message is too long to be displayed");
889
+ } else {
890
+ console.log(msg);
891
+ }
892
+ };
893
+
894
+ var node = new nep.Node("nep-cli-sub");
895
+ var conf = node.hybrid(master_ip);
896
+ sub = node.new_sub(topic, "json", callback, conf);
897
+ };
898
+
899
+ async function run(master_ip) {
900
+ var requester = new zmq.Request();
901
+ requester.connect("tcp://" + master_ip + ":" + PORT_MASTER_INFO);
902
+
903
+ let msg = { "input": "topics" };
904
+ var message = JSON.stringify(msg);
905
+ await requester.send(message);
906
+ const [result] = await requester.receive();
907
+ var results = JSON.parse(result.toString());
908
+
909
+ if (results["state"] === "failure") {
910
+ console.log("Topic is not registered");
911
+ } else {
912
+ console.log("");
913
+ if (results["input"].includes(topic)) {
914
+ opensub(master_ip);
915
+ } else {
916
+ console.log("Topic is not registered");
917
+ }
918
+ }
919
+ }
920
+
921
+ const wifiInterface = interfaces['Wi-Fi'] || interfaces['Wi-Fi 2'] || interfaces['wlan0'] || interfaces['wlo1'];
922
+ if (wifiInterface) {
923
+ const wifiIPv4 = wifiInterface.find(iface => iface.family === 'IPv4');
924
+ if (wifiIPv4) {
925
+ run(wifiIPv4.address);
926
+ } else {
927
+ console.log('No Wi-Fi IPv4 address found.');
928
+ }
929
+ } else {
930
+ console.log('Wi-Fi interface not found.');
931
+ }
932
+ });
933
+
934
+ program
935
+ .command('docs')
936
+ .description('Open the NEP+ documentation in the default browser')
937
+ .action(async () => {
938
+ const url = 'https://enrique-coronado.gitbook.io/nep-docs/';
939
+
940
+ try {
941
+ const open = await import('open');
942
+ open.default(url);
943
+ } catch (error) {
944
+ console.error('Error:', error.message);
945
+ }
946
+ });
947
+
948
+ function timeoutPromise(ms) {
949
+ return new Promise((resolve, reject) => {
950
+ setTimeout(() => {
951
+ reject(new Error("Request timed out"));
952
+ }, ms);
953
+ });
954
+ }
955
+
956
+ async function getAndDisplayTopics(master_ip) {
957
+ const TIMEOUT_DURATION = 5000;
958
+
959
+ var requester = new zmq.Request();
960
+ requester.connect(`tcp://${master_ip}:${PORT_MASTER_INFO}`);
961
+
962
+ let msg = { "input": "topics" };
963
+ var message = JSON.stringify(msg);
964
+
965
+ try {
966
+ const responsePromise = new Promise(async (resolve, reject) => {
967
+ await requester.send(message);
968
+ const [result] = await requester.receive();
969
+ var results = JSON.parse(result.toString());
970
+ resolve(results);
971
+ });
972
+
973
+ const timeoutPromise = new Promise((resolve, reject) => {
974
+ setTimeout(() => {
975
+ reject(new Error("Timed out, NEP master over Ethernet was not found"));
976
+ }, TIMEOUT_DURATION);
977
+ });
978
+
979
+ const results = await Promise.race([responsePromise, timeoutPromise]);
980
+
981
+ if (results["state"] === "success") {
982
+ availableTopics = results["input"];
983
+ console.log("");
984
+ results["input"].forEach(element => {
985
+ console.log(element);
986
+ });
987
+ } else {
988
+ console.log("No topics yet");
989
+ }
990
+ } catch (error) {
991
+ console.error("Error:", error.message);
992
+ } finally {
993
+ process.exit();
994
+ }
995
+ }
996
+
997
+ program.parse(process.argv);
998
+
999
+