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.
- package/bin/index.js +999 -834
- package/package.json +20 -16
package/bin/index.js
CHANGED
|
@@ -1,834 +1,999 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
var
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
await
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
var
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
console.log(
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
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
|
+
|