@atelieruldetehnologii/node-red-custome-solutions 0.62.22

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 (107) hide show
  1. package/NOTICE +56 -0
  2. package/PROPRIETARY-LICENSE.txt +157 -0
  3. package/README.md +105 -0
  4. package/TERMS-AND-CONDITIONS.md +311 -0
  5. package/advantech-read/advantech-read.html +775 -0
  6. package/advantech-read/advantech-read.js +449 -0
  7. package/advantech-write/advantech-write.html +413 -0
  8. package/advantech-write/advantech-write.js +338 -0
  9. package/bess-control/bess-control.html +569 -0
  10. package/bess-control/bess-control.js +541 -0
  11. package/bess-control/lib/allocation.js +149 -0
  12. package/bess-control/lib/batteries.js +86 -0
  13. package/bess-control/lib/helpers.js +157 -0
  14. package/bess-control/lib/messages.js +131 -0
  15. package/bess-control/lib/runtime.js +156 -0
  16. package/carlo-gavazzi/carlo-gavazzi.html +4327 -0
  17. package/carlo-gavazzi/carlo-gavazzi.js +3081 -0
  18. package/control-export/control-export.html +3644 -0
  19. package/control-export/control-export.js +2192 -0
  20. package/control-reactive/control-reactive.html +3136 -0
  21. package/control-reactive/control-reactive.js +2124 -0
  22. package/fronius-emulator/README.md +258 -0
  23. package/fronius-emulator/fronius-emulator.html +170 -0
  24. package/fronius-emulator/fronius-emulator.js +520 -0
  25. package/fronius-emulator/lib/binary-codec.js +65 -0
  26. package/fronius-emulator/lib/fronius-register-map.js +185 -0
  27. package/fronius-emulator/lib/modbus-parser.js +61 -0
  28. package/fronius-emulator/lib/modbus-tcp-server.js +224 -0
  29. package/fronius-emulator/lib/validation.js +206 -0
  30. package/fronius-emulator/lib/virtual-meter.js +132 -0
  31. package/fronius-read/fronius-read.html +3944 -0
  32. package/fronius-read/fronius-read.js +1466 -0
  33. package/fronius-read/lib/inverter-profiles.js +711 -0
  34. package/fronius-read/lib/sunspec-core.js +303 -0
  35. package/fronius-read/lib/sunspec-model-parsers.js +845 -0
  36. package/fronius-write/fronius-write.html +1789 -0
  37. package/fronius-write/fronius-write.js +2531 -0
  38. package/influxdb/influxdb.html +1077 -0
  39. package/influxdb/influxdb.js +1487 -0
  40. package/janitza/janitza.html +2562 -0
  41. package/janitza/janitza.js +1500 -0
  42. package/janitza/lib/janitza-profiles.js +371 -0
  43. package/lib/a3-test-server.js +199 -0
  44. package/lib/adam-6000-profiles.js +173 -0
  45. package/lib/licensing/constants.js +103 -0
  46. package/lib/licensing/device-id.js +251 -0
  47. package/lib/licensing/errors.js +21 -0
  48. package/lib/licensing/license-client.js +377 -0
  49. package/lib/licensing/license-state.js +50 -0
  50. package/lib/licensing/node-guard.js +150 -0
  51. package/lib/licensing/package-integrity.js +167 -0
  52. package/lib/licensing/package-integrity.json +513 -0
  53. package/lib/licensing/public-key.pem +3 -0
  54. package/lib/licensing/public-key.pem.example +2 -0
  55. package/lib/licensing/public-keys.js +18 -0
  56. package/lib/licensing/storage.js +63 -0
  57. package/lib/licensing/token-verifier.js +84 -0
  58. package/lib/numbers.js +26 -0
  59. package/license/atelier-license.html +88 -0
  60. package/license/atelier-license.js +170 -0
  61. package/modbus-tcp-discover/modbus-tcp-discover.html +190 -0
  62. package/modbus-tcp-discover/modbus-tcp-discover.js +706 -0
  63. package/multi-battery/multi-battery.html +649 -0
  64. package/multi-battery/multi-battery.js +668 -0
  65. package/multi-grid/multi-grid.html +745 -0
  66. package/multi-grid/multi-grid.js +1392 -0
  67. package/multi-inverter/lib/engine-core.js +237 -0
  68. package/multi-inverter/multi-inverter.html +2674 -0
  69. package/multi-inverter/multi-inverter.js +1393 -0
  70. package/package.json +109 -0
  71. package/phoenix-contact/lib/eem-ma370-advanced.js +175 -0
  72. package/phoenix-contact/lib/eem-ma370.js +138 -0
  73. package/phoenix-contact/lib/integrations.js +149 -0
  74. package/phoenix-contact/lib/phoenix-contact-profile.js +35030 -0
  75. package/phoenix-contact/phoenix-contact.html +840 -0
  76. package/phoenix-contact/phoenix-contact.js +679 -0
  77. package/pv-generator/pv-generator.html +284 -0
  78. package/pv-generator/pv-generator.js +387 -0
  79. package/pylontech-read/pylontech-read.html +763 -0
  80. package/pylontech-read/pylontech-read.js +518 -0
  81. package/pylontech-write/pylontech-write.html +405 -0
  82. package/pylontech-write/pylontech-write.js +546 -0
  83. package/scada-aggregator/lib/aggregate.js +72 -0
  84. package/scada-aggregator/lib/groups.js +39 -0
  85. package/scada-aggregator/scada-aggregator.html +108 -0
  86. package/scada-aggregator/scada-aggregator.js +117 -0
  87. package/scada-server/lib/aggregator-map.js +58 -0
  88. package/scada-server/lib/encoding.js +235 -0
  89. package/scada-server/lib/modbus-server.js +492 -0
  90. package/scada-server/lib/object-path.js +18 -0
  91. package/scada-server/lib/register-map.js +288 -0
  92. package/scada-server/scada-server.html +1419 -0
  93. package/scada-server/scada-server.js +704 -0
  94. package/scripts/check-syntax.js +66 -0
  95. package/scripts/package-integrity.js +46 -0
  96. package/scripts/package-release.js +116 -0
  97. package/scripts/run-tests.js +2178 -0
  98. package/scripts/tgz-integrity.js +74 -0
  99. package/sma-read/lib/sunspec-core.js +83 -0
  100. package/sma-read/lib/sunspec-model-parsers.js +853 -0
  101. package/sma-read/sma-read.html +659 -0
  102. package/sma-read/sma-read.js +458 -0
  103. package/sma-write/sma-write.html +105 -0
  104. package/sma-write/sma-write.js +270 -0
  105. package/victron-read/lib/mqtt-state.js +176 -0
  106. package/victron-read/victron-read.html +1074 -0
  107. package/victron-read/victron-read.js +1222 -0
@@ -0,0 +1,4327 @@
1
+ <style>
2
+
3
+
4
+ .carlo-gavazzi-editor {
5
+
6
+
7
+ --pr-border: #d7dde5;
8
+
9
+
10
+ --pr-muted: #667085;
11
+
12
+
13
+ --pr-surface: #f8fafc;
14
+
15
+
16
+ }
17
+
18
+
19
+
20
+ .carlo-gavazzi-editor .pr-section {
21
+
22
+
23
+ margin: 0 0 18px;
24
+
25
+
26
+ padding: 14px 16px 16px;
27
+
28
+
29
+ border: 1px solid var(--pr-border);
30
+
31
+
32
+ border-radius: 10px;
33
+
34
+
35
+ background: var(--pr-surface);
36
+
37
+
38
+ }
39
+
40
+
41
+
42
+ .carlo-gavazzi-editor .pr-section-title {
43
+
44
+
45
+ display: flex;
46
+
47
+
48
+ align-items: center;
49
+
50
+
51
+ gap: 8px;
52
+
53
+
54
+ margin: 0 0 4px;
55
+
56
+
57
+ font-size: 15px;
58
+
59
+
60
+ font-weight: 600;
61
+
62
+
63
+ color: #243447;
64
+
65
+
66
+ }
67
+
68
+
69
+
70
+ .carlo-gavazzi-editor .pr-section-note {
71
+
72
+
73
+ margin: 0 0 14px;
74
+
75
+
76
+ color: var(--pr-muted);
77
+
78
+
79
+ font-size: 12px;
80
+
81
+
82
+ line-height: 1.45;
83
+
84
+
85
+ }
86
+
87
+
88
+
89
+ .carlo-gavazzi-editor .pr-grid {
90
+
91
+
92
+ display: grid;
93
+
94
+
95
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
96
+
97
+
98
+ gap: 12px 16px;
99
+
100
+
101
+ }
102
+
103
+
104
+
105
+ .carlo-gavazzi-editor .pr-grid-2 {
106
+
107
+
108
+ grid-template-columns: repeat(2, minmax(320px, 1fr));
109
+
110
+
111
+ }
112
+
113
+
114
+
115
+ .carlo-gavazzi-editor .pr-span-2 {
116
+
117
+
118
+ grid-column: 1 / -1;
119
+
120
+
121
+ }
122
+
123
+
124
+
125
+ .carlo-gavazzi-editor .form-row {
126
+
127
+
128
+ margin-bottom: 12px;
129
+
130
+
131
+ }
132
+
133
+
134
+
135
+ .carlo-gavazzi-editor .pr-grid .form-row,
136
+
137
+
138
+ .carlo-gavazzi-editor .form-row:last-child {
139
+
140
+
141
+ margin-bottom: 0;
142
+
143
+
144
+ }
145
+
146
+
147
+
148
+ .carlo-gavazzi-editor .form-row > label {
149
+
150
+
151
+ width: 150px;
152
+
153
+
154
+ font-weight: 600;
155
+
156
+
157
+ }
158
+
159
+
160
+
161
+ .carlo-gavazzi-editor .form-row > input[type="text"],
162
+
163
+
164
+ .carlo-gavazzi-editor .form-row > input[type="number"],
165
+
166
+
167
+ .carlo-gavazzi-editor .form-row > select {
168
+
169
+
170
+ width: calc(100% - 160px);
171
+
172
+
173
+ }
174
+
175
+
176
+
177
+ .carlo-gavazzi-editor .pr-grid-2 .form-row > label {
178
+
179
+
180
+ width: 130px;
181
+
182
+
183
+ }
184
+
185
+
186
+
187
+ .carlo-gavazzi-editor .pr-grid-2 .form-row > input[type="text"],
188
+
189
+
190
+ .carlo-gavazzi-editor .pr-grid-2 .form-row > input[type="number"],
191
+
192
+
193
+ .carlo-gavazzi-editor .pr-grid-2 .form-row > select {
194
+
195
+
196
+ width: calc(100% - 140px);
197
+
198
+
199
+ }
200
+
201
+
202
+
203
+ .carlo-gavazzi-editor .pr-checkbox-row > input[type="checkbox"] {
204
+
205
+
206
+ display: inline-block;
207
+
208
+
209
+ width: auto;
210
+
211
+
212
+ vertical-align: top;
213
+
214
+
215
+ }
216
+
217
+
218
+
219
+ .carlo-gavazzi-editor .pr-inline-note {
220
+
221
+
222
+ margin-left: 8px;
223
+
224
+
225
+ color: var(--pr-muted);
226
+
227
+
228
+ line-height: 1.4;
229
+
230
+
231
+ }
232
+
233
+
234
+
235
+ .carlo-gavazzi-editor .pr-field-list {
236
+
237
+
238
+ max-height: 320px;
239
+
240
+
241
+ overflow: auto;
242
+
243
+
244
+ padding: 12px;
245
+
246
+
247
+ border: 1px solid var(--pr-border);
248
+
249
+
250
+ border-radius: 10px;
251
+
252
+
253
+ background: #fff;
254
+
255
+
256
+ }
257
+
258
+
259
+
260
+ .carlo-gavazzi-editor .pr-field-group {
261
+
262
+
263
+ margin-bottom: 14px;
264
+
265
+
266
+ }
267
+
268
+
269
+
270
+ .carlo-gavazzi-editor .pr-field-group:last-child {
271
+
272
+
273
+ margin-bottom: 0;
274
+
275
+
276
+ }
277
+
278
+
279
+
280
+ .carlo-gavazzi-editor .pr-field-group-title {
281
+
282
+
283
+ margin: 0 0 8px;
284
+
285
+
286
+ font-size: 12px;
287
+
288
+
289
+ font-weight: 700;
290
+
291
+
292
+ text-transform: uppercase;
293
+
294
+
295
+ letter-spacing: 0.03em;
296
+
297
+
298
+ color: #344054;
299
+
300
+
301
+ }
302
+
303
+
304
+
305
+ .carlo-gavazzi-editor .pr-field-group-grid {
306
+
307
+
308
+ display: grid;
309
+
310
+
311
+ grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
312
+
313
+
314
+ gap: 8px 16px;
315
+
316
+
317
+ }
318
+
319
+
320
+
321
+ .carlo-gavazzi-editor .pr-field-item {
322
+
323
+
324
+ display: flex;
325
+
326
+
327
+ align-items: center;
328
+
329
+
330
+ gap: 8px;
331
+
332
+
333
+ margin: 0;
334
+
335
+
336
+ line-height: 1.35;
337
+
338
+
339
+ }
340
+
341
+
342
+
343
+ .carlo-gavazzi-editor .pr-toolbar {
344
+
345
+
346
+ display: flex;
347
+
348
+
349
+ flex-wrap: wrap;
350
+
351
+
352
+ gap: 8px;
353
+
354
+
355
+ margin-bottom: 10px;
356
+
357
+
358
+ }
359
+
360
+
361
+
362
+ .carlo-gavazzi-editor .pr-inline-control {
363
+
364
+
365
+ width: calc(100% - 160px);
366
+
367
+
368
+ }
369
+
370
+
371
+
372
+ @media (max-width: 1100px) {
373
+
374
+
375
+ .carlo-gavazzi-editor .pr-grid-2 {
376
+
377
+
378
+ grid-template-columns: 1fr;
379
+
380
+
381
+ }
382
+
383
+
384
+ }
385
+
386
+
387
+
388
+ </style>
389
+
390
+
391
+
392
+ <script type="text/javascript">
393
+
394
+
395
+ (function () {
396
+
397
+
398
+
399
+ const FIELD_GROUPS = [
400
+
401
+
402
+ {
403
+
404
+
405
+ label: "General",
406
+
407
+
408
+ fields: [
409
+
410
+
411
+ "summary.power.total_w",
412
+
413
+
414
+ "summary.frequency_hz",
415
+
416
+
417
+ "summary.phase_sequence"
418
+
419
+
420
+ ]
421
+
422
+
423
+ },
424
+
425
+
426
+ {
427
+
428
+
429
+ label: "Voltage",
430
+
431
+
432
+ fields: [
433
+
434
+
435
+ "summary.voltage.l1_n_v",
436
+
437
+
438
+ "summary.voltage.l2_n_v",
439
+
440
+
441
+ "summary.voltage.l3_n_v",
442
+
443
+
444
+ "summary.voltage.l1_l2_v",
445
+
446
+
447
+ "summary.voltage.l2_l3_v",
448
+
449
+
450
+ "summary.voltage.l3_l1_v"
451
+
452
+
453
+ ]
454
+
455
+
456
+ },
457
+
458
+
459
+ {
460
+
461
+
462
+ label: "Current",
463
+
464
+
465
+ fields: [
466
+
467
+
468
+ "summary.current.l1_a",
469
+
470
+
471
+ "summary.current.l2_a",
472
+
473
+
474
+ "summary.current.l3_a"
475
+
476
+
477
+ ]
478
+
479
+
480
+ },
481
+
482
+
483
+ {
484
+
485
+
486
+ label: "Active Power",
487
+
488
+
489
+ fields: [
490
+
491
+
492
+ "summary.power.l1_w",
493
+
494
+
495
+ "summary.power.l2_w",
496
+
497
+
498
+ "summary.power.l3_w"
499
+
500
+
501
+ ]
502
+
503
+
504
+ },
505
+
506
+
507
+ {
508
+
509
+
510
+ label: "Apparent Power",
511
+
512
+
513
+ fields: [
514
+
515
+
516
+ "summary.apparent.l1_va",
517
+
518
+
519
+ "summary.apparent.l2_va",
520
+
521
+
522
+ "summary.apparent.l3_va",
523
+
524
+
525
+ "summary.apparent.total_va"
526
+
527
+
528
+ ]
529
+
530
+
531
+ },
532
+
533
+
534
+ {
535
+
536
+
537
+ label: "Reactive Power",
538
+
539
+
540
+ fields: [
541
+
542
+
543
+ "summary.reactive.l1_var",
544
+
545
+
546
+ "summary.reactive.l2_var",
547
+
548
+
549
+ "summary.reactive.l3_var",
550
+
551
+
552
+ "summary.reactive.total_var"
553
+
554
+
555
+ ]
556
+
557
+
558
+ },
559
+
560
+
561
+ {
562
+
563
+
564
+ label: "Power Factor",
565
+
566
+
567
+ fields: [
568
+
569
+
570
+ "summary.power_factor.l1",
571
+
572
+
573
+ "summary.power_factor.l2",
574
+
575
+
576
+ "summary.power_factor.l3"
577
+
578
+
579
+ ]
580
+
581
+
582
+ },
583
+
584
+
585
+ {
586
+
587
+
588
+ label: "Energy",
589
+
590
+
591
+ fields: [
592
+
593
+
594
+ "summary.energy.import_kwh",
595
+
596
+
597
+ "summary.energy.reactive_import_kvarh",
598
+
599
+
600
+ "summary.energy.export_kwh",
601
+
602
+
603
+ "summary.energy.export_reactive_kvarh",
604
+
605
+
606
+ "summary.energy.l1_kwh",
607
+
608
+
609
+ "summary.energy.l2_kwh",
610
+
611
+
612
+ "summary.energy.l3_kwh"
613
+
614
+
615
+ ]
616
+
617
+
618
+ },
619
+
620
+
621
+ {
622
+
623
+
624
+ label: "Tariff Energy",
625
+
626
+
627
+ fields: [
628
+
629
+
630
+ "summary.energy.tariff.t1_kwh",
631
+
632
+
633
+ "summary.energy.tariff.t2_kwh",
634
+
635
+
636
+ "summary.energy.tariff.t3_kwh",
637
+
638
+
639
+ "summary.energy.tariff.t4_kwh",
640
+
641
+
642
+ "summary.energy.reactive_tariff.t1_kvarh",
643
+
644
+
645
+ "summary.energy.reactive_tariff.t2_kvarh",
646
+
647
+
648
+ "summary.energy.reactive_tariff.t3_kvarh",
649
+
650
+
651
+ "summary.energy.reactive_tariff.t4_kvarh"
652
+
653
+
654
+ ]
655
+
656
+
657
+ }
658
+
659
+
660
+ ];
661
+
662
+
663
+
664
+ const MULTI_GRID_DEFAULT_FIELDS = [
665
+
666
+
667
+ "summary.power.total_w",
668
+
669
+
670
+ "summary.power.l1_w",
671
+
672
+
673
+ "summary.power.l2_w",
674
+
675
+
676
+ "summary.power.l3_w"
677
+
678
+
679
+ ];
680
+
681
+
682
+ const BESS_CONTROL_DEFAULT_FIELDS = [
683
+
684
+
685
+ "summary.power.total_w",
686
+
687
+
688
+ "summary.power.l1_w",
689
+
690
+
691
+ "summary.power.l2_w",
692
+
693
+
694
+ "summary.power.l3_w"
695
+
696
+
697
+ ];
698
+
699
+
700
+ const CONTROL_EXPORT_REACTIVE_DEFAULT_FIELDS = [
701
+
702
+
703
+ "summary.power.total_w",
704
+
705
+
706
+ "summary.power.l1_w",
707
+
708
+
709
+ "summary.power.l2_w",
710
+
711
+
712
+ "summary.power.l3_w",
713
+
714
+
715
+ "summary.reactive.total_var",
716
+
717
+
718
+ "summary.reactive.l1_var",
719
+
720
+
721
+ "summary.reactive.l2_var",
722
+
723
+
724
+ "summary.reactive.l3_var"
725
+
726
+
727
+ ];
728
+
729
+
730
+ const SCADA_DEFAULT_FIELDS = [
731
+
732
+
733
+ "summary.power.total_w",
734
+
735
+
736
+ "summary.reactive.total_var",
737
+
738
+
739
+ "summary.frequency_hz",
740
+
741
+
742
+ "summary.voltage.l1_l2_v",
743
+
744
+
745
+ "summary.voltage.l2_l3_v",
746
+
747
+
748
+ "summary.voltage.l3_l1_v"
749
+
750
+
751
+ ];
752
+
753
+
754
+
755
+ let payloadSelectionState = ["full"];
756
+
757
+
758
+ let customModeSelections = {
759
+
760
+
761
+ multiGrid: [],
762
+
763
+
764
+ bessControl: [],
765
+
766
+
767
+ controlExportReactive: [],
768
+
769
+
770
+ scadaServer: [],
771
+
772
+
773
+ influxDb: []
774
+
775
+
776
+ };
777
+
778
+
779
+ let customModeEnabledState = {
780
+
781
+
782
+ multiGrid: false,
783
+
784
+
785
+ bessControl: false,
786
+
787
+
788
+ controlExportReactive: false,
789
+
790
+
791
+ scadaServer: false,
792
+
793
+
794
+ influxDb: false
795
+
796
+
797
+ };
798
+
799
+
800
+ let specialExpertUnlockedState = {
801
+
802
+
803
+ multiGrid: false,
804
+
805
+
806
+ bessControl: false,
807
+
808
+
809
+ controlExportReactive: false,
810
+
811
+
812
+ scadaServer: false,
813
+
814
+
815
+ influxDb: false
816
+
817
+
818
+ };
819
+
820
+
821
+ let specialLongPressTimer = null;
822
+
823
+
824
+ let specialLongPressTriggeredMode = "";
825
+
826
+
827
+ let specialLongPressStartChecked = false;
828
+
829
+
830
+ let specialLongPressActivationMode = "";
831
+
832
+
833
+ const SPECIAL_EXPERT_LONG_PRESS_MS = 5000;
834
+
835
+
836
+
837
+ function getSelectedOutputCount(nodeLike) {
838
+
839
+
840
+ if (nodeLike && nodeLike.multiGrid) {
841
+
842
+
843
+ return 1;
844
+
845
+
846
+ }
847
+
848
+
849
+
850
+ if (nodeLike && nodeLike.bessControl) {
851
+
852
+
853
+ return 1;
854
+
855
+
856
+ }
857
+
858
+
859
+ if (nodeLike && nodeLike.controlExportReactive) {
860
+
861
+
862
+ return 1;
863
+
864
+
865
+ }
866
+
867
+
868
+
869
+ if (nodeLike && nodeLike.scadaServer) {
870
+
871
+
872
+ return 1;
873
+
874
+
875
+ }
876
+
877
+
878
+
879
+ if (nodeLike && nodeLike.influxDb) {
880
+
881
+
882
+ return 1;
883
+
884
+
885
+ }
886
+
887
+
888
+
889
+ const fields = Array.isArray(nodeLike && nodeLike.payloadFields)
890
+
891
+
892
+ ? nodeLike.payloadFields.filter(Boolean)
893
+
894
+
895
+ : ["full"];
896
+
897
+
898
+
899
+ if (!fields.length || fields.includes("full")) {
900
+
901
+
902
+ return 1;
903
+
904
+
905
+ }
906
+
907
+
908
+
909
+ return Math.max(1, fields.length);
910
+
911
+
912
+ }
913
+
914
+
915
+
916
+ function normalizeSelectedValues(value, allowEmpty) {
917
+
918
+
919
+ const keepEmpty = !!allowEmpty;
920
+
921
+
922
+
923
+ if (Array.isArray(value)) {
924
+
925
+
926
+ const filtered = value.map(function (v) {
927
+
928
+
929
+ return String(v || "").trim();
930
+
931
+
932
+ }).filter(Boolean);
933
+
934
+
935
+
936
+ return filtered.length ? filtered : (keepEmpty ? [] : ["full"]);
937
+
938
+
939
+ }
940
+
941
+
942
+
943
+ if (typeof value === "string") {
944
+
945
+
946
+ const trimmed = value.trim();
947
+
948
+
949
+
950
+ if (!trimmed) {
951
+
952
+
953
+ return keepEmpty ? [] : ["full"];
954
+
955
+
956
+ }
957
+
958
+
959
+
960
+ if (trimmed[0] === "[") {
961
+
962
+
963
+ try {
964
+
965
+
966
+ const parsed = JSON.parse(trimmed);
967
+
968
+
969
+ if (Array.isArray(parsed)) {
970
+
971
+
972
+ return normalizeSelectedValues(parsed, keepEmpty);
973
+
974
+
975
+ }
976
+
977
+
978
+ } catch (e) {
979
+
980
+
981
+ // ignore
982
+
983
+
984
+ }
985
+
986
+
987
+ }
988
+
989
+
990
+
991
+ return [trimmed];
992
+
993
+
994
+ }
995
+
996
+
997
+
998
+ return keepEmpty ? [] : ["full"];
999
+
1000
+
1001
+ }
1002
+
1003
+
1004
+
1005
+ function dedupeSelectedValues(values, allowEmpty) {
1006
+
1007
+
1008
+ return Array.from(new Set(normalizeSelectedValues(values, allowEmpty)));
1009
+
1010
+
1011
+ }
1012
+
1013
+
1014
+
1015
+ function sanitizeSelectedValues(values, allowEmpty) {
1016
+
1017
+
1018
+ const keepEmpty = !!allowEmpty;
1019
+
1020
+
1021
+ const normalized = dedupeSelectedValues(values, keepEmpty).filter(Boolean);
1022
+
1023
+
1024
+
1025
+ if (normalized.includes("full") && normalized.length > 1) {
1026
+
1027
+
1028
+ return normalized.filter(function (v) {
1029
+
1030
+
1031
+ return v !== "full";
1032
+
1033
+
1034
+ });
1035
+
1036
+
1037
+ }
1038
+
1039
+
1040
+
1041
+ return normalized.length ? normalized : (keepEmpty ? [] : ["full"]);
1042
+
1043
+
1044
+ }
1045
+
1046
+
1047
+
1048
+ function getActiveSpecialMode(multiGrid, bessControl, controlExportReactive, scadaServer, influxDb) {
1049
+
1050
+
1051
+ if (multiGrid) {
1052
+
1053
+
1054
+ return "multiGrid";
1055
+
1056
+
1057
+ }
1058
+
1059
+
1060
+ if (bessControl) {
1061
+
1062
+
1063
+ return "bessControl";
1064
+
1065
+
1066
+ }
1067
+
1068
+
1069
+ if (controlExportReactive) {
1070
+
1071
+
1072
+ return "controlExportReactive";
1073
+
1074
+
1075
+ }
1076
+
1077
+
1078
+ if (scadaServer) {
1079
+
1080
+
1081
+ return "scadaServer";
1082
+
1083
+
1084
+ }
1085
+
1086
+
1087
+ if (influxDb) {
1088
+
1089
+
1090
+ return "influxDb";
1091
+
1092
+
1093
+ }
1094
+
1095
+
1096
+ return "";
1097
+
1098
+
1099
+ }
1100
+
1101
+
1102
+
1103
+ function getDefaultFieldsForMode(mode) {
1104
+
1105
+
1106
+ if (mode === "multiGrid") {
1107
+
1108
+
1109
+ return MULTI_GRID_DEFAULT_FIELDS.slice();
1110
+
1111
+
1112
+ }
1113
+
1114
+
1115
+ if (mode === "bessControl") {
1116
+
1117
+
1118
+ return BESS_CONTROL_DEFAULT_FIELDS.slice();
1119
+
1120
+
1121
+ }
1122
+
1123
+
1124
+ if (mode === "controlExportReactive") {
1125
+
1126
+
1127
+ return CONTROL_EXPORT_REACTIVE_DEFAULT_FIELDS.slice();
1128
+
1129
+
1130
+ }
1131
+
1132
+
1133
+ if (mode === "scadaServer") {
1134
+
1135
+
1136
+ return SCADA_DEFAULT_FIELDS.slice();
1137
+
1138
+
1139
+ }
1140
+
1141
+
1142
+ if (mode === "influxDb") {
1143
+
1144
+
1145
+ const allSelectable = getAllSelectableFields();
1146
+ const filtered = allSelectable.filter(function (field) {
1147
+ return String(field || "").indexOf("summary.energy.") !== 0;
1148
+ });
1149
+
1150
+ return filtered.length ? filtered : allSelectable;
1151
+
1152
+
1153
+ }
1154
+
1155
+
1156
+ return ["full"];
1157
+
1158
+
1159
+ }
1160
+
1161
+
1162
+
1163
+ function isSpecialModeEnabled(mode) {
1164
+
1165
+
1166
+ return mode === "multiGrid" || mode === "bessControl" || mode === "controlExportReactive" || mode === "scadaServer" || mode === "influxDb";
1167
+
1168
+
1169
+ }
1170
+
1171
+
1172
+
1173
+ function getModeCheckbox(mode) {
1174
+
1175
+
1176
+ if (mode === "multiGrid") {
1177
+
1178
+
1179
+ return $("#node-input-multiGrid");
1180
+
1181
+
1182
+ }
1183
+
1184
+
1185
+ if (mode === "bessControl") {
1186
+
1187
+
1188
+ return $("#node-input-bessControl");
1189
+
1190
+
1191
+ }
1192
+
1193
+
1194
+ if (mode === "controlExportReactive") {
1195
+
1196
+
1197
+ return $("#node-input-controlExportReactive");
1198
+
1199
+
1200
+ }
1201
+
1202
+
1203
+ if (mode === "scadaServer") {
1204
+
1205
+
1206
+ return $("#node-input-scadaServer");
1207
+
1208
+
1209
+ }
1210
+
1211
+
1212
+ if (mode === "influxDb") {
1213
+
1214
+
1215
+ return $("#node-input-influxDb");
1216
+
1217
+
1218
+ }
1219
+
1220
+
1221
+ return $();
1222
+
1223
+
1224
+ }
1225
+
1226
+
1227
+
1228
+ function arraysEqual(a, b) {
1229
+
1230
+
1231
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
1232
+
1233
+
1234
+ return false;
1235
+
1236
+
1237
+ }
1238
+
1239
+
1240
+
1241
+ let i;
1242
+
1243
+
1244
+ for (i = 0; i < a.length; i += 1) {
1245
+
1246
+
1247
+ if (a[i] !== b[i]) {
1248
+
1249
+
1250
+ return false;
1251
+
1252
+
1253
+ }
1254
+
1255
+
1256
+ }
1257
+
1258
+
1259
+
1260
+ return true;
1261
+
1262
+
1263
+ }
1264
+
1265
+
1266
+
1267
+ function sanitizeCustomModeSelection(values) {
1268
+
1269
+
1270
+ return sanitizeSelectedValues(values, true).filter(function (v) {
1271
+
1272
+
1273
+ return v !== "full";
1274
+
1275
+
1276
+ });
1277
+
1278
+
1279
+ }
1280
+
1281
+
1282
+
1283
+ function getAllSelectableFields() {
1284
+
1285
+
1286
+ const allFields = [];
1287
+
1288
+
1289
+ const seen = new Set();
1290
+
1291
+
1292
+
1293
+ FIELD_GROUPS.forEach(function (group) {
1294
+
1295
+
1296
+ group.fields.forEach(function (field) {
1297
+
1298
+
1299
+ if (seen.has(field)) {
1300
+
1301
+
1302
+ return;
1303
+
1304
+
1305
+ }
1306
+
1307
+
1308
+ seen.add(field);
1309
+
1310
+
1311
+ allFields.push(field);
1312
+
1313
+
1314
+ });
1315
+
1316
+
1317
+ });
1318
+
1319
+
1320
+
1321
+ return allFields;
1322
+
1323
+
1324
+ }
1325
+
1326
+
1327
+
1328
+ function sanitizeForMode(values, multiGrid, bessControl, controlExportReactive, scadaServer, influxDb, options) {
1329
+
1330
+
1331
+ const mode = getActiveSpecialMode(multiGrid, bessControl, controlExportReactive, scadaServer, influxDb);
1332
+
1333
+
1334
+ const allowEmptySpecial = !!(options && options.allowEmptySpecial && mode);
1335
+
1336
+
1337
+ const normalized = sanitizeSelectedValues(values, allowEmptySpecial);
1338
+
1339
+
1340
+
1341
+ if (mode && normalized.includes("full")) {
1342
+
1343
+
1344
+ return getDefaultFieldsForMode(mode);
1345
+
1346
+
1347
+ }
1348
+
1349
+
1350
+
1351
+ return normalized;
1352
+
1353
+
1354
+ }
1355
+
1356
+
1357
+
1358
+ function applyExclusiveSelectionRule(selected, changedValue, checked) {
1359
+
1360
+
1361
+ let unique = Array.from(new Set((selected || []).filter(Boolean)));
1362
+
1363
+
1364
+
1365
+ if (changedValue === "full") {
1366
+
1367
+
1368
+ if (checked) {
1369
+
1370
+
1371
+ return ["full"];
1372
+
1373
+
1374
+ }
1375
+
1376
+
1377
+ unique = unique.filter(function (v) {
1378
+
1379
+
1380
+ return v !== "full";
1381
+
1382
+
1383
+ });
1384
+
1385
+
1386
+ return unique.length ? unique : ["full"];
1387
+
1388
+
1389
+ }
1390
+
1391
+
1392
+
1393
+ if (checked) {
1394
+
1395
+
1396
+ unique = unique.filter(function (v) {
1397
+
1398
+
1399
+ return v !== "full";
1400
+
1401
+
1402
+ });
1403
+
1404
+
1405
+ return unique.length ? unique : ["full"];
1406
+
1407
+
1408
+ }
1409
+
1410
+
1411
+
1412
+ unique = unique.filter(function (v) {
1413
+
1414
+
1415
+ return v !== changedValue;
1416
+
1417
+
1418
+ });
1419
+
1420
+
1421
+
1422
+ return unique.length ? unique : ["full"];
1423
+
1424
+
1425
+ }
1426
+
1427
+
1428
+
1429
+ function getPayloadLabel(path) {
1430
+
1431
+
1432
+ const labels = {
1433
+
1434
+
1435
+ "full": "Toate valorile",
1436
+
1437
+
1438
+ "summary.power.total_w": "Putere totala (W)",
1439
+
1440
+
1441
+ "summary.frequency_hz": "Frecventa (Hz)",
1442
+
1443
+
1444
+ "summary.phase_sequence": "Ordine faze",
1445
+
1446
+
1447
+
1448
+ "summary.voltage.l1_n_v": "Tensiune L1-N (V)",
1449
+
1450
+
1451
+ "summary.voltage.l2_n_v": "Tensiune L2-N (V)",
1452
+
1453
+
1454
+ "summary.voltage.l3_n_v": "Tensiune L3-N (V)",
1455
+
1456
+
1457
+ "summary.voltage.l1_l2_v": "Tensiune L1-L2 (V)",
1458
+
1459
+
1460
+ "summary.voltage.l2_l3_v": "Tensiune L2-L3 (V)",
1461
+
1462
+
1463
+ "summary.voltage.l3_l1_v": "Tensiune L3-L1 (V)",
1464
+
1465
+
1466
+
1467
+ "summary.current.l1_a": "Curent L1 (A)",
1468
+
1469
+
1470
+ "summary.current.l2_a": "Curent L2 (A)",
1471
+
1472
+
1473
+ "summary.current.l3_a": "Curent L3 (A)",
1474
+
1475
+
1476
+
1477
+ "summary.power.l1_w": "Putere L1 (W)",
1478
+
1479
+
1480
+ "summary.power.l2_w": "Putere L2 (W)",
1481
+
1482
+
1483
+ "summary.power.l3_w": "Putere L3 (W)",
1484
+
1485
+
1486
+
1487
+ "summary.apparent.l1_va": "Putere aparenta L1 (VA)",
1488
+
1489
+
1490
+ "summary.apparent.l2_va": "Putere aparenta L2 (VA)",
1491
+
1492
+
1493
+ "summary.apparent.l3_va": "Putere aparenta L3 (VA)",
1494
+
1495
+
1496
+ "summary.apparent.total_va": "Putere aparenta totala (VA)",
1497
+
1498
+
1499
+
1500
+ "summary.reactive.l1_var": "Putere reactiva L1 (var)",
1501
+
1502
+
1503
+ "summary.reactive.l2_var": "Putere reactiva L2 (var)",
1504
+
1505
+
1506
+ "summary.reactive.l3_var": "Putere reactiva L3 (var)",
1507
+
1508
+
1509
+ "summary.reactive.total_var": "Putere reactiva totala (var)",
1510
+
1511
+
1512
+
1513
+ "summary.power_factor.l1": "Factor putere L1",
1514
+
1515
+
1516
+ "summary.power_factor.l2": "Factor putere L2",
1517
+
1518
+
1519
+ "summary.power_factor.l3": "Factor putere L3",
1520
+
1521
+
1522
+
1523
+ "summary.energy.import_kwh": "Energie importata (kWh)",
1524
+
1525
+
1526
+ "summary.energy.reactive_import_kvarh": "Energie reactiva importata (kvarh)",
1527
+
1528
+
1529
+ "summary.energy.export_kwh": "Energie exportata (kWh)",
1530
+
1531
+
1532
+ "summary.energy.export_reactive_kvarh": "Energie reactiva exportata (kvarh)",
1533
+
1534
+
1535
+ "summary.energy.l1_kwh": "Energie L1 (kWh)",
1536
+
1537
+
1538
+ "summary.energy.l2_kwh": "Energie L2 (kWh)",
1539
+
1540
+
1541
+ "summary.energy.l3_kwh": "Energie L3 (kWh)",
1542
+
1543
+
1544
+ "summary.energy.tariff.t1_kwh": "Energie T1 (kWh)",
1545
+
1546
+
1547
+ "summary.energy.tariff.t2_kwh": "Energie T2 (kWh)",
1548
+
1549
+
1550
+ "summary.energy.tariff.t3_kwh": "Energie T3 (kWh)",
1551
+
1552
+
1553
+ "summary.energy.tariff.t4_kwh": "Energie T4 (kWh)",
1554
+
1555
+
1556
+ "summary.energy.reactive_tariff.t1_kvarh": "Energie reactiva T1 (kvarh)",
1557
+
1558
+
1559
+ "summary.energy.reactive_tariff.t2_kvarh": "Energie reactiva T2 (kvarh)",
1560
+
1561
+
1562
+ "summary.energy.reactive_tariff.t3_kvarh": "Energie reactiva T3 (kvarh)",
1563
+
1564
+
1565
+ "summary.energy.reactive_tariff.t4_kvarh": "Energie reactiva T4 (kvarh)"
1566
+
1567
+
1568
+ };
1569
+
1570
+
1571
+
1572
+ return labels[path] || path;
1573
+
1574
+
1575
+ }
1576
+
1577
+
1578
+
1579
+ function renderFieldSelection(selectedValues) {
1580
+
1581
+
1582
+ const specialMode = getActiveSpecialMode(
1583
+
1584
+
1585
+ $("#node-input-multiGrid").is(":checked"),
1586
+
1587
+
1588
+ $("#node-input-bessControl").is(":checked"),
1589
+
1590
+
1591
+ $("#node-input-controlExportReactive").is(":checked"),
1592
+
1593
+
1594
+ $("#node-input-scadaServer").is(":checked"),
1595
+
1596
+
1597
+ $("#node-input-influxDb").is(":checked")
1598
+
1599
+
1600
+ );
1601
+
1602
+
1603
+ const expertMode = $("#node-input-expertMode").is(":checked");
1604
+
1605
+
1606
+ const specialModeCustomEnabled = !!(specialMode && customModeEnabledState[specialMode]);
1607
+
1608
+
1609
+ const normalized = sanitizeForMode(
1610
+
1611
+
1612
+ selectedValues,
1613
+
1614
+
1615
+ $("#node-input-multiGrid").is(":checked"),
1616
+
1617
+
1618
+ $("#node-input-bessControl").is(":checked"),
1619
+
1620
+
1621
+ $("#node-input-controlExportReactive").is(":checked"),
1622
+
1623
+
1624
+ $("#node-input-scadaServer").is(":checked"),
1625
+
1626
+
1627
+ $("#node-input-influxDb").is(":checked"),
1628
+
1629
+
1630
+ { allowEmptySpecial: !!(specialMode && (expertMode || specialModeCustomEnabled)) }
1631
+
1632
+
1633
+ );
1634
+
1635
+
1636
+ const $container = $("#node-carlo-gavazzi-field-list-container");
1637
+
1638
+
1639
+ const renderedFields = new Set();
1640
+
1641
+
1642
+
1643
+ $container.empty();
1644
+
1645
+
1646
+
1647
+ FIELD_GROUPS.forEach(function (group) {
1648
+
1649
+
1650
+ const $group = $('<div class="pr-field-group"></div>');
1651
+
1652
+
1653
+ const $title = $('<p class="pr-field-group-title"></p>').text(group.label);
1654
+
1655
+
1656
+ const $grid = $('<div class="pr-field-group-grid"></div>');
1657
+
1658
+
1659
+ let groupHasFields = false;
1660
+
1661
+
1662
+
1663
+ group.fields.forEach(function (field) {
1664
+
1665
+
1666
+ if (renderedFields.has(field)) {
1667
+
1668
+
1669
+ return;
1670
+
1671
+
1672
+ }
1673
+
1674
+
1675
+ renderedFields.add(field);
1676
+
1677
+
1678
+ groupHasFields = true;
1679
+
1680
+
1681
+ const checkboxId = "carlo-gavazzi-field-" + field.replace(/[^a-zA-Z0-9_]/g, "_");
1682
+
1683
+
1684
+ const $checkbox = $('<input type="checkbox" class="pr-field-checkbox">')
1685
+
1686
+
1687
+ .attr("id", checkboxId)
1688
+
1689
+
1690
+ .attr("data-field", field)
1691
+
1692
+
1693
+ .prop("checked", normalized.includes(field));
1694
+
1695
+
1696
+ const $label = $('<label class="pr-field-item"></label>')
1697
+
1698
+
1699
+ .attr("for", checkboxId)
1700
+
1701
+
1702
+ .append($checkbox)
1703
+
1704
+
1705
+ .append($('<span></span>').text(getPayloadLabel(field)));
1706
+
1707
+
1708
+
1709
+ $grid.append($label);
1710
+
1711
+
1712
+ });
1713
+
1714
+
1715
+
1716
+ if (groupHasFields) {
1717
+
1718
+
1719
+ $group.append($title).append($grid);
1720
+
1721
+
1722
+ $container.append($group);
1723
+
1724
+
1725
+ }
1726
+
1727
+
1728
+ });
1729
+
1730
+
1731
+
1732
+ $container.find(".pr-field-checkbox").off(".carloFields").on("change.carloFields", function () {
1733
+
1734
+
1735
+ const selected = [];
1736
+
1737
+
1738
+ $container.find(".pr-field-checkbox:checked").each(function () {
1739
+
1740
+
1741
+ selected.push($(this).attr("data-field"));
1742
+
1743
+
1744
+ });
1745
+
1746
+
1747
+
1748
+ persistPayloadSelection(selected, { allowEmptySpecial: true });
1749
+
1750
+
1751
+ syncPayloadModeUi();
1752
+
1753
+
1754
+ });
1755
+
1756
+
1757
+ }
1758
+
1759
+
1760
+
1761
+ function persistPayloadSelection(values, options) {
1762
+
1763
+
1764
+ const multiGrid = $("#node-input-multiGrid").is(":checked");
1765
+
1766
+
1767
+ const bessControl = $("#node-input-bessControl").is(":checked");
1768
+
1769
+
1770
+ const controlExportReactive = $("#node-input-controlExportReactive").is(":checked");
1771
+
1772
+
1773
+ const scadaServer = $("#node-input-scadaServer").is(":checked");
1774
+
1775
+
1776
+ const influxDb = $("#node-input-influxDb").is(":checked");
1777
+
1778
+
1779
+ const mode = getActiveSpecialMode(multiGrid, bessControl, controlExportReactive, scadaServer, influxDb);
1780
+
1781
+
1782
+ const expertMode = $("#node-input-expertMode").is(":checked");
1783
+
1784
+
1785
+ const modeCustomEnabled = !!(mode && customModeEnabledState[mode]);
1786
+
1787
+
1788
+ const allowEmptySpecial = !!(options && options.allowEmptySpecial && mode && (expertMode || modeCustomEnabled));
1789
+
1790
+
1791
+
1792
+ payloadSelectionState = sanitizeForMode(
1793
+
1794
+
1795
+ values,
1796
+
1797
+
1798
+ multiGrid,
1799
+
1800
+
1801
+ bessControl,
1802
+
1803
+
1804
+ controlExportReactive,
1805
+
1806
+
1807
+ scadaServer,
1808
+
1809
+
1810
+ influxDb,
1811
+
1812
+
1813
+ { allowEmptySpecial: allowEmptySpecial }
1814
+
1815
+
1816
+ );
1817
+
1818
+
1819
+ $("#node-input-payloadFields").val(JSON.stringify(payloadSelectionState));
1820
+
1821
+
1822
+
1823
+ if (mode && (expertMode || modeCustomEnabled)) {
1824
+
1825
+
1826
+ customModeSelections[mode] = sanitizeCustomModeSelection(payloadSelectionState);
1827
+
1828
+
1829
+ }
1830
+
1831
+
1832
+
1833
+ const isMultiGrid = multiGrid;
1834
+
1835
+
1836
+ const isBessControl = bessControl;
1837
+
1838
+
1839
+ const isControlExportReactive = controlExportReactive;
1840
+
1841
+
1842
+ const isScadaServer = scadaServer;
1843
+
1844
+
1845
+ const isInfluxDb = influxDb;
1846
+
1847
+
1848
+ $("#node-input-outputs").val((isMultiGrid || isBessControl || isControlExportReactive || isScadaServer || isInfluxDb) ? 1 : (payloadSelectionState.includes("full") ? 1 : Math.max(1, payloadSelectionState.length)));
1849
+
1850
+
1851
+ }
1852
+
1853
+
1854
+
1855
+ function syncPayloadModeUi() {
1856
+
1857
+
1858
+ const multiGrid = $("#node-input-multiGrid").is(":checked");
1859
+
1860
+
1861
+ const bessControl = $("#node-input-bessControl").is(":checked");
1862
+
1863
+
1864
+ const controlExportReactive = $("#node-input-controlExportReactive").is(":checked");
1865
+
1866
+
1867
+ const scadaServer = $("#node-input-scadaServer").is(":checked");
1868
+
1869
+
1870
+ const influxDb = $("#node-input-influxDb").is(":checked");
1871
+
1872
+
1873
+ const specialMode = getActiveSpecialMode(multiGrid, bessControl, controlExportReactive, scadaServer, influxDb);
1874
+
1875
+
1876
+ if (!specialMode) {
1877
+
1878
+
1879
+ $("#node-input-expertMode").prop("checked", false);
1880
+
1881
+
1882
+ }
1883
+
1884
+
1885
+ const expertMode = $("#node-input-expertMode").is(":checked");
1886
+
1887
+
1888
+ const specialModeCustomEnabled = !!(specialMode && customModeEnabledState[specialMode]);
1889
+
1890
+
1891
+ const selectedMode = specialMode ? "selected" : ($("#node-input-payloadMode").val() || "full");
1892
+
1893
+
1894
+ const showSelectedFields = selectedMode === "selected" && (!specialMode || expertMode);
1895
+
1896
+
1897
+ const showDefaultButton = showSelectedFields && !!specialMode;
1898
+
1899
+
1900
+
1901
+ $("#node-input-payloadMode").val(selectedMode);
1902
+
1903
+
1904
+ $("#row-carlo-gavazzi-field-list").toggle(showSelectedFields);
1905
+
1906
+
1907
+ $("#row-expert-mode").toggle(!!specialMode && !!specialExpertUnlockedState[specialMode]);
1908
+
1909
+
1910
+ $("#node-carlo-gavazzi-default-values").toggle(showDefaultButton);
1911
+
1912
+
1913
+
1914
+ if (specialMode && !expertMode) {
1915
+
1916
+
1917
+ payloadSelectionState = (specialModeCustomEnabled ? customModeSelections[specialMode] : getDefaultFieldsForMode(specialMode)).slice();
1918
+
1919
+
1920
+ $("#node-input-payloadFields").val(JSON.stringify(payloadSelectionState));
1921
+
1922
+
1923
+ $("#node-input-outputs").val(1);
1924
+
1925
+
1926
+ } else if (!showSelectedFields) {
1927
+
1928
+
1929
+ persistPayloadSelection(["full"]);
1930
+
1931
+
1932
+ } else if (specialMode && expertMode) {
1933
+
1934
+
1935
+ if (payloadSelectionState.includes("full")) {
1936
+
1937
+
1938
+ payloadSelectionState = customModeSelections[specialMode].slice();
1939
+
1940
+
1941
+ }
1942
+
1943
+
1944
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
1945
+
1946
+
1947
+ } else if (payloadSelectionState.includes("full")) {
1948
+
1949
+
1950
+ persistPayloadSelection([]);
1951
+
1952
+
1953
+ }
1954
+
1955
+
1956
+
1957
+ renderFieldSelection(payloadSelectionState);
1958
+
1959
+
1960
+ }
1961
+
1962
+
1963
+
1964
+ function clearSpecialLongPressTimer() {
1965
+
1966
+
1967
+ if (specialLongPressTimer) {
1968
+
1969
+
1970
+ clearTimeout(specialLongPressTimer);
1971
+
1972
+
1973
+ specialLongPressTimer = null;
1974
+
1975
+
1976
+ }
1977
+
1978
+
1979
+ }
1980
+
1981
+
1982
+
1983
+ function unlockSpecialExpertMode(mode) {
1984
+
1985
+
1986
+ if (!isSpecialModeEnabled(mode)) {
1987
+
1988
+
1989
+ return;
1990
+
1991
+
1992
+ }
1993
+
1994
+
1995
+
1996
+ specialExpertUnlockedState[mode] = true;
1997
+
1998
+
1999
+ $("#node-input-expertMode").prop("checked", true).trigger("change");
2000
+
2001
+
2002
+ syncPayloadModeUi();
2003
+
2004
+
2005
+ if (RED && RED.notify) {
2006
+
2007
+
2008
+ RED.notify("Selectia custom a fost activata.", "success");
2009
+
2010
+
2011
+ }
2012
+
2013
+
2014
+ }
2015
+
2016
+
2017
+
2018
+ function setupSpecialModeLongPress() {
2019
+
2020
+
2021
+ function startLongPress(mode) {
2022
+
2023
+
2024
+ const $checkbox = getModeCheckbox(mode);
2025
+
2026
+
2027
+ if (!$checkbox.length || specialExpertUnlockedState[mode]) {
2028
+
2029
+
2030
+ return;
2031
+
2032
+
2033
+ }
2034
+
2035
+
2036
+
2037
+ specialLongPressTriggeredMode = "";
2038
+
2039
+
2040
+ specialLongPressStartChecked = $checkbox.is(":checked");
2041
+
2042
+
2043
+ clearSpecialLongPressTimer();
2044
+
2045
+
2046
+
2047
+ specialLongPressTimer = setTimeout(function () {
2048
+
2049
+
2050
+ if (specialLongPressStartChecked && $checkbox.is(":checked")) {
2051
+
2052
+
2053
+ specialLongPressTriggeredMode = mode;
2054
+
2055
+
2056
+ unlockSpecialExpertMode(mode);
2057
+
2058
+
2059
+ }
2060
+
2061
+
2062
+ }, SPECIAL_EXPERT_LONG_PRESS_MS);
2063
+
2064
+
2065
+ }
2066
+
2067
+
2068
+
2069
+ function stopLongPress() {
2070
+
2071
+
2072
+ clearSpecialLongPressTimer();
2073
+
2074
+
2075
+ }
2076
+
2077
+
2078
+
2079
+ ["multiGrid", "bessControl", "controlExportReactive", "scadaServer", "influxDb"].forEach(function (mode) {
2080
+
2081
+
2082
+ const $checkbox = getModeCheckbox(mode);
2083
+
2084
+
2085
+ $checkbox
2086
+
2087
+
2088
+ .off(".carloSpecialLongPress")
2089
+
2090
+
2091
+ .on("mousedown.carloSpecialLongPress touchstart.carloSpecialLongPress", function () {
2092
+
2093
+
2094
+ startLongPress(mode);
2095
+
2096
+
2097
+ })
2098
+
2099
+
2100
+ .on("mouseup.carloSpecialLongPress mouseleave.carloSpecialLongPress touchend.carloSpecialLongPress touchcancel.carloSpecialLongPress", function () {
2101
+
2102
+
2103
+ stopLongPress();
2104
+
2105
+
2106
+ })
2107
+
2108
+
2109
+ .on("click.carloSpecialLongPress", function (evt) {
2110
+
2111
+
2112
+ if (specialLongPressTriggeredMode !== mode) {
2113
+
2114
+
2115
+ return;
2116
+
2117
+
2118
+ }
2119
+
2120
+
2121
+ evt.preventDefault();
2122
+
2123
+
2124
+ evt.stopImmediatePropagation();
2125
+
2126
+
2127
+ specialLongPressActivationMode = mode;
2128
+
2129
+
2130
+ $checkbox.prop("checked", true).trigger("change");
2131
+
2132
+
2133
+ specialLongPressTriggeredMode = "";
2134
+
2135
+
2136
+ });
2137
+
2138
+
2139
+ });
2140
+
2141
+
2142
+ }
2143
+
2144
+
2145
+
2146
+ function toggleMultiGridFields() {
2147
+
2148
+
2149
+ const multiGrid = $("#node-input-multiGrid").is(":checked");
2150
+
2151
+
2152
+ const bessControl = $("#node-input-bessControl").is(":checked");
2153
+
2154
+
2155
+ const controlExportReactive = $("#node-input-controlExportReactive").is(":checked");
2156
+
2157
+
2158
+ const scadaServer = $("#node-input-scadaServer").is(":checked");
2159
+
2160
+
2161
+ const influxDb = $("#node-input-influxDb").is(":checked");
2162
+
2163
+
2164
+ const specialMode = multiGrid || bessControl || controlExportReactive || scadaServer || influxDb;
2165
+
2166
+
2167
+
2168
+ if (specialMode) {
2169
+
2170
+
2171
+ $("#row-meter-id").show();
2172
+
2173
+
2174
+ } else {
2175
+
2176
+
2177
+ $("#row-meter-id").hide();
2178
+
2179
+
2180
+ }
2181
+
2182
+
2183
+
2184
+ $("#node-input-payloadMode").prop("disabled", multiGrid || bessControl || controlExportReactive || scadaServer || influxDb);
2185
+
2186
+
2187
+ $("#row-influx-measurement,#row-influx-node").toggle(influxDb);
2188
+
2189
+
2190
+ syncPayloadModeUi();
2191
+
2192
+
2193
+ }
2194
+
2195
+
2196
+
2197
+ RED.nodes.registerType("carlo-gavazzi", {
2198
+
2199
+
2200
+ category: "Atelierul de Tehnologii",
2201
+
2202
+
2203
+ color: "#c7e9c0",
2204
+
2205
+
2206
+ defaults: {
2207
+ license: { value: "", type: "atelier-license", required: true },
2208
+
2209
+
2210
+ name: { value: "" },
2211
+
2212
+
2213
+ host: { value: "", required: true },
2214
+
2215
+
2216
+ port: { value: 502, required: true, validate: RED.validators.number() },
2217
+
2218
+
2219
+ unitId: { value: 1, required: true, validate: RED.validators.number() },
2220
+
2221
+
2222
+ timestep: {
2223
+ value: 1000,
2224
+ required: true,
2225
+ validate: function (v) {
2226
+ const text = String(v || "").trim().toLowerCase();
2227
+ const n = Number(text);
2228
+ return text === "off" || (Number.isFinite(n) && n >= 0);
2229
+ }
2230
+ },
2231
+
2232
+
2233
+ payloadFields: { value: ["full"] },
2234
+
2235
+
2236
+ payloadMode: { value: "full" },
2237
+
2238
+
2239
+ multiGrid: { value: false },
2240
+
2241
+
2242
+ bessControl: { value: false },
2243
+
2244
+
2245
+ controlExportReactive: { value: false },
2246
+
2247
+
2248
+ scadaServer: { value: false },
2249
+
2250
+
2251
+ influxDb: { value: false },
2252
+
2253
+
2254
+ influxMeasurement: {
2255
+
2256
+
2257
+ value: "",
2258
+
2259
+
2260
+ validate: function (v) {
2261
+
2262
+
2263
+ const influxChecked = $("#node-input-influxDb").length
2264
+
2265
+
2266
+ ? $("#node-input-influxDb").is(":checked")
2267
+
2268
+
2269
+ : !!this.influxDb;
2270
+
2271
+
2272
+
2273
+ return !influxChecked || !!String(v || "").trim();
2274
+
2275
+
2276
+ }
2277
+
2278
+
2279
+ },
2280
+
2281
+
2282
+ expertMode: { value: false },
2283
+
2284
+
2285
+ multiGridCustomFields: { value: [] },
2286
+
2287
+
2288
+ bessControlCustomFields: { value: [] },
2289
+
2290
+
2291
+ controlExportReactiveCustomFields: { value: [] },
2292
+
2293
+
2294
+ scadaServerCustomFields: { value: [] },
2295
+
2296
+
2297
+ influxNode: { value: "" },
2298
+ influxDbCustomFields: { value: [] },
2299
+
2300
+
2301
+ multiGridUseSelectedFields: { value: false },
2302
+
2303
+
2304
+ bessControlUseSelectedFields: { value: false },
2305
+
2306
+
2307
+ controlExportReactiveUseSelectedFields: { value: false },
2308
+
2309
+
2310
+ scadaServerUseSelectedFields: { value: false },
2311
+
2312
+
2313
+ influxDbUseSelectedFields: { value: false },
2314
+
2315
+
2316
+ meterId: {
2317
+
2318
+
2319
+ value: "",
2320
+
2321
+
2322
+ validate: function (v) {
2323
+
2324
+
2325
+ const isSpecial = (
2326
+
2327
+
2328
+ $("#node-input-multiGrid").is(":checked") ||
2329
+
2330
+
2331
+ $("#node-input-bessControl").is(":checked") ||
2332
+
2333
+
2334
+ $("#node-input-controlExportReactive").is(":checked") ||
2335
+
2336
+
2337
+ $("#node-input-scadaServer").is(":checked") ||
2338
+
2339
+
2340
+ $("#node-input-influxDb").is(":checked")
2341
+
2342
+
2343
+ );
2344
+
2345
+
2346
+ if (!isSpecial) {
2347
+
2348
+
2349
+ return true;
2350
+
2351
+
2352
+ }
2353
+
2354
+
2355
+ return !!String(v || "").trim();
2356
+
2357
+
2358
+ }
2359
+
2360
+
2361
+ },
2362
+
2363
+
2364
+ outputs: { value: 1 }
2365
+
2366
+
2367
+ },
2368
+
2369
+
2370
+ inputs: 0,
2371
+
2372
+
2373
+ outputs: 1,
2374
+
2375
+
2376
+ icon: "bridge.svg",
2377
+
2378
+
2379
+ label: function () {
2380
+
2381
+
2382
+ if (this.name && String(this.name).trim()) {
2383
+
2384
+
2385
+ return this.name;
2386
+
2387
+
2388
+ }
2389
+
2390
+
2391
+
2392
+ if (this.host && String(this.host).trim()) {
2393
+
2394
+
2395
+ return String(this.host).trim();
2396
+
2397
+
2398
+ }
2399
+
2400
+
2401
+
2402
+ return "carlo-gavazzi";
2403
+
2404
+
2405
+ },
2406
+
2407
+
2408
+ oneditprepare: function () {
2409
+ const node = this;
2410
+ const influxSelect = $("#node-input-influxNode").empty().append($("<option></option>").val("").text("Selecteaza adt-influxdb"));
2411
+ RED.nodes.eachNode(function (candidate) {
2412
+ if (candidate.type === "adt-influxdb") influxSelect.append($("<option></option>").val(candidate.id).text(candidate.name || "adt-influxdb"));
2413
+ });
2414
+ influxSelect.val(node.influxNode || "");
2415
+
2416
+ function syncInputs() {
2417
+ const text = String($("#node-input-timestep").val() || "").trim().toLowerCase();
2418
+ node.inputs = text === "off" || text === "0" ? 1 : 0;
2419
+ }
2420
+
2421
+ $("#node-input-timestep").off(".carloPoll").on("keyup.carloPoll change.carloPoll", syncInputs);
2422
+ syncInputs();
2423
+
2424
+
2425
+ const specialMode = getActiveSpecialMode(!!this.multiGrid, !!this.bessControl, !!this.controlExportReactive, !!this.scadaServer, !!this.influxDb);
2426
+
2427
+
2428
+
2429
+ customModeSelections = {
2430
+
2431
+
2432
+ multiGrid: sanitizeCustomModeSelection(this.multiGridCustomFields),
2433
+
2434
+
2435
+ bessControl: sanitizeCustomModeSelection(this.bessControlCustomFields),
2436
+
2437
+
2438
+ controlExportReactive: sanitizeCustomModeSelection(this.controlExportReactiveCustomFields),
2439
+
2440
+
2441
+ scadaServer: sanitizeCustomModeSelection(this.scadaServerCustomFields),
2442
+
2443
+
2444
+ influxDb: sanitizeCustomModeSelection(this.influxDbCustomFields)
2445
+
2446
+
2447
+ };
2448
+
2449
+
2450
+ customModeEnabledState = {
2451
+
2452
+
2453
+ multiGrid: !!this.multiGridUseSelectedFields,
2454
+
2455
+
2456
+ bessControl: !!this.bessControlUseSelectedFields,
2457
+
2458
+
2459
+ controlExportReactive: !!this.controlExportReactiveUseSelectedFields,
2460
+
2461
+
2462
+ scadaServer: !!this.scadaServerUseSelectedFields,
2463
+
2464
+
2465
+ influxDb: !!this.influxDbUseSelectedFields
2466
+
2467
+
2468
+ };
2469
+
2470
+
2471
+ if (specialMode && this.expertMode) {
2472
+
2473
+
2474
+ customModeEnabledState[specialMode] = true;
2475
+
2476
+
2477
+ }
2478
+
2479
+
2480
+ specialExpertUnlockedState = {
2481
+
2482
+
2483
+ multiGrid: false,
2484
+
2485
+
2486
+ bessControl: false,
2487
+
2488
+
2489
+ controlExportReactive: false,
2490
+
2491
+
2492
+ scadaServer: false,
2493
+
2494
+
2495
+ influxDb: false
2496
+
2497
+
2498
+ };
2499
+
2500
+
2501
+
2502
+ const currentPayloadFields = sanitizeForMode(
2503
+
2504
+
2505
+ this.payloadFields || ["full"],
2506
+
2507
+
2508
+ !!this.multiGrid,
2509
+
2510
+
2511
+ !!this.bessControl,
2512
+
2513
+
2514
+ !!this.controlExportReactive,
2515
+
2516
+
2517
+ !!this.scadaServer,
2518
+
2519
+
2520
+ !!this.influxDb,
2521
+
2522
+
2523
+ { allowEmptySpecial: !!(specialMode && (this.expertMode || customModeEnabledState[specialMode])) }
2524
+
2525
+
2526
+ );
2527
+
2528
+
2529
+ const initialPayloadMode = (this.multiGrid || this.bessControl || this.controlExportReactive || this.scadaServer || this.influxDb) ? "selected" : ((currentPayloadFields.includes("full") || !currentPayloadFields.length) ? "full" : "selected");
2530
+
2531
+
2532
+ const savedName = String(this.name || "").trim();
2533
+ const savedHost = String(this.host || "").trim();
2534
+ let nameManuallyEdited = !!savedName && savedName !== savedHost && savedName !== "carlo-gavazzi";
2535
+
2536
+
2537
+
2538
+ if (!this.name && this.host) {
2539
+
2540
+
2541
+ $("#node-input-name").val(this.host);
2542
+
2543
+
2544
+ }
2545
+
2546
+
2547
+
2548
+ payloadSelectionState = (specialMode && (this.expertMode || customModeEnabledState[specialMode]))
2549
+
2550
+
2551
+ ? customModeSelections[specialMode].slice()
2552
+
2553
+
2554
+ : currentPayloadFields.slice();
2555
+
2556
+
2557
+ $("#node-input-payloadMode").val(initialPayloadMode);
2558
+
2559
+
2560
+ $("#node-input-expertMode").prop("checked", false);
2561
+
2562
+
2563
+ $("#node-input-payloadFields").val(JSON.stringify(payloadSelectionState));
2564
+
2565
+
2566
+ $("#node-input-outputs").val(getSelectedOutputCount({
2567
+
2568
+
2569
+ multiGrid: $("#node-input-multiGrid").is(":checked"),
2570
+
2571
+
2572
+ bessControl: $("#node-input-bessControl").is(":checked"),
2573
+
2574
+
2575
+ controlExportReactive: $("#node-input-controlExportReactive").is(":checked"),
2576
+
2577
+
2578
+ scadaServer: $("#node-input-scadaServer").is(":checked"),
2579
+
2580
+
2581
+ influxDb: $("#node-input-influxDb").is(":checked"),
2582
+
2583
+
2584
+ payloadFields: currentPayloadFields
2585
+
2586
+
2587
+ }));
2588
+
2589
+
2590
+
2591
+ renderFieldSelection(currentPayloadFields);
2592
+
2593
+
2594
+
2595
+ $("#node-input-name")
2596
+
2597
+
2598
+ .off(".carloName")
2599
+
2600
+
2601
+ .on("input.carloName", function () {
2602
+
2603
+
2604
+ const currentName = String($(this).val() || "").trim();
2605
+ const currentHost = String($("#node-input-host").val() || "").trim();
2606
+ nameManuallyEdited = !!currentName && currentName !== currentHost;
2607
+
2608
+
2609
+ });
2610
+
2611
+
2612
+
2613
+ $("#node-input-host")
2614
+
2615
+
2616
+ .off(".carloHostSync")
2617
+
2618
+
2619
+ .on("input.carloHostSync change.carloHostSync", function () {
2620
+
2621
+
2622
+ const newHost = String($(this).val() || "").trim();
2623
+
2624
+
2625
+ if (newHost || !$("#node-input-name").val().trim()) {
2626
+
2627
+
2628
+ $("#node-input-name").val(newHost);
2629
+
2630
+
2631
+ }
2632
+
2633
+
2634
+ });
2635
+
2636
+
2637
+ $("#node-input-payloadMode")
2638
+
2639
+
2640
+ .off(".carloPayloadMode")
2641
+
2642
+
2643
+ .on("change.carloPayloadMode", function () {
2644
+
2645
+
2646
+ syncPayloadModeUi();
2647
+
2648
+
2649
+ });
2650
+
2651
+
2652
+ $("#node-input-expertMode")
2653
+
2654
+
2655
+ .off(".carloExpert")
2656
+
2657
+
2658
+ .on("change.carloExpert", function () {
2659
+
2660
+
2661
+ const activeMode = getActiveSpecialMode(
2662
+
2663
+
2664
+ $("#node-input-multiGrid").is(":checked"),
2665
+
2666
+
2667
+ $("#node-input-bessControl").is(":checked"),
2668
+
2669
+
2670
+ $("#node-input-controlExportReactive").is(":checked"),
2671
+
2672
+
2673
+ $("#node-input-scadaServer").is(":checked"),
2674
+
2675
+
2676
+ $("#node-input-influxDb").is(":checked")
2677
+
2678
+
2679
+ );
2680
+
2681
+
2682
+
2683
+ if (activeMode) {
2684
+
2685
+
2686
+ if ($(this).is(":checked")) {
2687
+
2688
+
2689
+ customModeEnabledState[activeMode] = true;
2690
+
2691
+
2692
+ payloadSelectionState = customModeSelections[activeMode].slice();
2693
+
2694
+
2695
+ } else if (specialExpertUnlockedState[activeMode]) {
2696
+
2697
+
2698
+ customModeEnabledState[activeMode] = false;
2699
+
2700
+
2701
+ customModeSelections[activeMode] = sanitizeCustomModeSelection(payloadSelectionState);
2702
+
2703
+
2704
+ }
2705
+
2706
+
2707
+ }
2708
+
2709
+
2710
+ syncPayloadModeUi();
2711
+
2712
+
2713
+ });
2714
+
2715
+
2716
+
2717
+ $("#node-carlo-gavazzi-select-all")
2718
+
2719
+
2720
+ .off(".carloToolbar")
2721
+
2722
+
2723
+ .on("click.carloToolbar", function (evt) {
2724
+
2725
+
2726
+ evt.preventDefault();
2727
+
2728
+
2729
+ persistPayloadSelection(getAllSelectableFields(), { allowEmptySpecial: true });
2730
+
2731
+
2732
+ syncPayloadModeUi();
2733
+
2734
+
2735
+ });
2736
+
2737
+
2738
+
2739
+ $("#node-carlo-gavazzi-clear-all")
2740
+
2741
+
2742
+ .off(".carloToolbar")
2743
+
2744
+
2745
+ .on("click.carloToolbar", function (evt) {
2746
+
2747
+
2748
+ evt.preventDefault();
2749
+
2750
+
2751
+ persistPayloadSelection([], { allowEmptySpecial: true });
2752
+
2753
+
2754
+ syncPayloadModeUi();
2755
+
2756
+
2757
+ });
2758
+
2759
+
2760
+
2761
+ $("#node-carlo-gavazzi-default-values")
2762
+
2763
+
2764
+ .off(".carloToolbar")
2765
+
2766
+
2767
+ .on("click.carloToolbar", function (evt) {
2768
+
2769
+
2770
+ evt.preventDefault();
2771
+
2772
+
2773
+ const mode = getActiveSpecialMode(
2774
+
2775
+
2776
+ $("#node-input-multiGrid").is(":checked"),
2777
+
2778
+
2779
+ $("#node-input-bessControl").is(":checked"),
2780
+
2781
+
2782
+ $("#node-input-controlExportReactive").is(":checked"),
2783
+
2784
+
2785
+ $("#node-input-scadaServer").is(":checked"),
2786
+
2787
+
2788
+ $("#node-input-influxDb").is(":checked")
2789
+
2790
+
2791
+ );
2792
+
2793
+
2794
+
2795
+ if (!mode) {
2796
+
2797
+
2798
+ return;
2799
+
2800
+
2801
+ }
2802
+
2803
+
2804
+
2805
+ persistPayloadSelection(getDefaultFieldsForMode(mode), { allowEmptySpecial: true });
2806
+
2807
+
2808
+ syncPayloadModeUi();
2809
+
2810
+
2811
+ });
2812
+
2813
+
2814
+
2815
+ $("#node-input-multiGrid")
2816
+
2817
+
2818
+ .off(".carloMulti")
2819
+
2820
+
2821
+ .on("change.carloMulti", function () {
2822
+
2823
+
2824
+ const activatedByLongPress = specialLongPressActivationMode === "multiGrid";
2825
+
2826
+
2827
+ const previousMode = getActiveSpecialMode(
2828
+
2829
+
2830
+ !$(this).is(":checked"),
2831
+
2832
+
2833
+ $("#node-input-bessControl").is(":checked"),
2834
+
2835
+
2836
+ $("#node-input-controlExportReactive").is(":checked"),
2837
+
2838
+
2839
+ $("#node-input-scadaServer").is(":checked"),
2840
+
2841
+
2842
+ $("#node-input-influxDb").is(":checked")
2843
+
2844
+
2845
+ );
2846
+
2847
+
2848
+ if (previousMode && ($("#node-input-expertMode").is(":checked") || customModeEnabledState[previousMode])) {
2849
+
2850
+
2851
+ customModeSelections[previousMode] = sanitizeCustomModeSelection(payloadSelectionState);
2852
+
2853
+
2854
+ }
2855
+
2856
+
2857
+ if ($(this).is(":checked")) {
2858
+
2859
+
2860
+ $("#node-input-bessControl").prop("checked", false);
2861
+
2862
+
2863
+ $("#node-input-controlExportReactive").prop("checked", false);
2864
+
2865
+
2866
+ $("#node-input-scadaServer").prop("checked", false);
2867
+
2868
+
2869
+ // InfluxDB poate ramane activ impreuna cu integrarea principala.
2870
+
2871
+
2872
+ if (!activatedByLongPress) {
2873
+
2874
+
2875
+ $("#node-input-expertMode").prop("checked", false);
2876
+
2877
+
2878
+ specialExpertUnlockedState.multiGrid = false;
2879
+
2880
+
2881
+ specialExpertUnlockedState.bessControl = false;
2882
+
2883
+
2884
+ specialExpertUnlockedState.controlExportReactive = false;
2885
+
2886
+
2887
+ specialExpertUnlockedState.scadaServer = false;
2888
+
2889
+
2890
+ specialExpertUnlockedState.influxDb = false;
2891
+
2892
+
2893
+ } else {
2894
+
2895
+
2896
+ specialExpertUnlockedState.multiGrid = true;
2897
+
2898
+
2899
+ }
2900
+
2901
+
2902
+ } else {
2903
+
2904
+
2905
+ specialExpertUnlockedState.multiGrid = false;
2906
+
2907
+
2908
+ }
2909
+
2910
+
2911
+ specialLongPressActivationMode = "";
2912
+
2913
+
2914
+ toggleMultiGridFields();
2915
+
2916
+
2917
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
2918
+
2919
+
2920
+ });
2921
+
2922
+
2923
+ $("#node-input-bessControl")
2924
+
2925
+
2926
+ .off(".carloBess")
2927
+
2928
+
2929
+ .on("change.carloBess", function () {
2930
+
2931
+
2932
+ const activatedByLongPress = specialLongPressActivationMode === "bessControl";
2933
+
2934
+
2935
+ const previousMode = getActiveSpecialMode(
2936
+
2937
+
2938
+ $("#node-input-multiGrid").is(":checked"),
2939
+
2940
+
2941
+ !$(this).is(":checked"),
2942
+
2943
+
2944
+ $("#node-input-controlExportReactive").is(":checked"),
2945
+
2946
+
2947
+ $("#node-input-scadaServer").is(":checked"),
2948
+
2949
+
2950
+ $("#node-input-influxDb").is(":checked")
2951
+
2952
+
2953
+ );
2954
+
2955
+
2956
+ if (previousMode && ($("#node-input-expertMode").is(":checked") || customModeEnabledState[previousMode])) {
2957
+
2958
+
2959
+ customModeSelections[previousMode] = sanitizeCustomModeSelection(payloadSelectionState);
2960
+
2961
+
2962
+ }
2963
+
2964
+
2965
+ if ($(this).is(":checked")) {
2966
+
2967
+
2968
+ $("#node-input-multiGrid").prop("checked", false);
2969
+
2970
+
2971
+ $("#node-input-controlExportReactive").prop("checked", false);
2972
+
2973
+
2974
+ $("#node-input-scadaServer").prop("checked", false);
2975
+
2976
+
2977
+ // InfluxDB poate ramane activ impreuna cu integrarea principala.
2978
+
2979
+
2980
+ if (!activatedByLongPress) {
2981
+
2982
+
2983
+ $("#node-input-expertMode").prop("checked", false);
2984
+
2985
+
2986
+ specialExpertUnlockedState.multiGrid = false;
2987
+
2988
+
2989
+ specialExpertUnlockedState.bessControl = false;
2990
+
2991
+
2992
+ specialExpertUnlockedState.controlExportReactive = false;
2993
+
2994
+
2995
+ specialExpertUnlockedState.scadaServer = false;
2996
+
2997
+
2998
+ specialExpertUnlockedState.influxDb = false;
2999
+
3000
+
3001
+ } else {
3002
+
3003
+
3004
+ specialExpertUnlockedState.bessControl = true;
3005
+
3006
+
3007
+ }
3008
+
3009
+
3010
+ } else {
3011
+
3012
+
3013
+ specialExpertUnlockedState.bessControl = false;
3014
+
3015
+
3016
+ }
3017
+
3018
+
3019
+ specialLongPressActivationMode = "";
3020
+
3021
+
3022
+ toggleMultiGridFields();
3023
+
3024
+
3025
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
3026
+
3027
+
3028
+ });
3029
+
3030
+
3031
+
3032
+ $("#node-input-controlExportReactive")
3033
+
3034
+
3035
+ .off(".carloCER")
3036
+
3037
+
3038
+ .on("change.carloCER", function () {
3039
+
3040
+
3041
+ const activatedByLongPress = specialLongPressActivationMode === "controlExportReactive";
3042
+
3043
+
3044
+ const previousMode = getActiveSpecialMode(
3045
+
3046
+
3047
+ $("#node-input-multiGrid").is(":checked"),
3048
+
3049
+
3050
+ $("#node-input-bessControl").is(":checked"),
3051
+
3052
+
3053
+ !$(this).is(":checked"),
3054
+
3055
+
3056
+ $("#node-input-scadaServer").is(":checked"),
3057
+
3058
+
3059
+ $("#node-input-influxDb").is(":checked")
3060
+
3061
+
3062
+ );
3063
+
3064
+
3065
+ if (previousMode && ($("#node-input-expertMode").is(":checked") || customModeEnabledState[previousMode])) {
3066
+
3067
+
3068
+ customModeSelections[previousMode] = sanitizeCustomModeSelection(payloadSelectionState);
3069
+
3070
+
3071
+ }
3072
+
3073
+
3074
+ if ($(this).is(":checked")) {
3075
+
3076
+
3077
+ $("#node-input-multiGrid").prop("checked", false);
3078
+
3079
+
3080
+ $("#node-input-bessControl").prop("checked", false);
3081
+
3082
+
3083
+ $("#node-input-scadaServer").prop("checked", false);
3084
+
3085
+
3086
+ // InfluxDB poate ramane activ impreuna cu integrarea principala.
3087
+
3088
+
3089
+ if (!activatedByLongPress) {
3090
+
3091
+
3092
+ $("#node-input-expertMode").prop("checked", false);
3093
+
3094
+
3095
+ specialExpertUnlockedState.multiGrid = false;
3096
+
3097
+
3098
+ specialExpertUnlockedState.bessControl = false;
3099
+
3100
+
3101
+ specialExpertUnlockedState.controlExportReactive = false;
3102
+
3103
+
3104
+ specialExpertUnlockedState.scadaServer = false;
3105
+
3106
+
3107
+ specialExpertUnlockedState.influxDb = false;
3108
+
3109
+
3110
+ } else {
3111
+
3112
+
3113
+ specialExpertUnlockedState.controlExportReactive = true;
3114
+
3115
+
3116
+ }
3117
+
3118
+
3119
+ } else {
3120
+
3121
+
3122
+ specialExpertUnlockedState.controlExportReactive = false;
3123
+
3124
+
3125
+ }
3126
+
3127
+
3128
+ specialLongPressActivationMode = "";
3129
+
3130
+
3131
+ toggleMultiGridFields();
3132
+
3133
+
3134
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
3135
+
3136
+
3137
+ });
3138
+
3139
+
3140
+
3141
+ $("#node-input-scadaServer")
3142
+
3143
+
3144
+ .off(".carloScada")
3145
+
3146
+
3147
+ .on("change.carloScada", function () {
3148
+
3149
+
3150
+ const activatedByLongPress = specialLongPressActivationMode === "scadaServer";
3151
+
3152
+
3153
+ const previousMode = getActiveSpecialMode(
3154
+
3155
+
3156
+ $("#node-input-multiGrid").is(":checked"),
3157
+
3158
+
3159
+ $("#node-input-bessControl").is(":checked"),
3160
+
3161
+
3162
+ $("#node-input-controlExportReactive").is(":checked"),
3163
+
3164
+
3165
+ !$(this).is(":checked"),
3166
+
3167
+
3168
+ $("#node-input-influxDb").is(":checked")
3169
+
3170
+
3171
+ );
3172
+
3173
+
3174
+ if (previousMode && ($("#node-input-expertMode").is(":checked") || customModeEnabledState[previousMode])) {
3175
+
3176
+
3177
+ customModeSelections[previousMode] = sanitizeCustomModeSelection(payloadSelectionState);
3178
+
3179
+
3180
+ }
3181
+
3182
+
3183
+ if ($(this).is(":checked")) {
3184
+
3185
+
3186
+ $("#node-input-multiGrid").prop("checked", false);
3187
+
3188
+
3189
+ $("#node-input-bessControl").prop("checked", false);
3190
+
3191
+
3192
+ $("#node-input-controlExportReactive").prop("checked", false);
3193
+
3194
+
3195
+ // InfluxDB poate ramane activ impreuna cu integrarea principala.
3196
+
3197
+
3198
+ if (!activatedByLongPress) {
3199
+
3200
+
3201
+ $("#node-input-expertMode").prop("checked", false);
3202
+
3203
+
3204
+ specialExpertUnlockedState.multiGrid = false;
3205
+
3206
+
3207
+ specialExpertUnlockedState.bessControl = false;
3208
+
3209
+
3210
+ specialExpertUnlockedState.controlExportReactive = false;
3211
+
3212
+
3213
+ specialExpertUnlockedState.scadaServer = false;
3214
+
3215
+
3216
+ specialExpertUnlockedState.influxDb = false;
3217
+
3218
+
3219
+ } else {
3220
+
3221
+
3222
+ specialExpertUnlockedState.scadaServer = true;
3223
+
3224
+
3225
+ }
3226
+
3227
+
3228
+ } else {
3229
+
3230
+
3231
+ specialExpertUnlockedState.scadaServer = false;
3232
+
3233
+
3234
+ }
3235
+
3236
+
3237
+ specialLongPressActivationMode = "";
3238
+
3239
+
3240
+ toggleMultiGridFields();
3241
+
3242
+
3243
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
3244
+
3245
+
3246
+ });
3247
+
3248
+
3249
+
3250
+ $("#node-input-influxDb")
3251
+
3252
+
3253
+ .off(".carloInflux")
3254
+
3255
+
3256
+ .on("change.carloInflux", function () {
3257
+
3258
+
3259
+ const activatedByLongPress = specialLongPressActivationMode === "influxDb";
3260
+
3261
+
3262
+ const previousMode = getActiveSpecialMode(
3263
+
3264
+
3265
+ $("#node-input-multiGrid").is(":checked"),
3266
+
3267
+
3268
+ $("#node-input-bessControl").is(":checked"),
3269
+
3270
+
3271
+ $("#node-input-controlExportReactive").is(":checked"),
3272
+
3273
+
3274
+ $("#node-input-scadaServer").is(":checked"),
3275
+
3276
+
3277
+ !$(this).is(":checked")
3278
+
3279
+
3280
+ );
3281
+
3282
+
3283
+ if (previousMode && ($("#node-input-expertMode").is(":checked") || customModeEnabledState[previousMode])) {
3284
+
3285
+
3286
+ customModeSelections[previousMode] = sanitizeCustomModeSelection(payloadSelectionState);
3287
+
3288
+
3289
+ }
3290
+
3291
+
3292
+ if ($(this).is(":checked")) {
3293
+
3294
+
3295
+ // Pastreaza cel mult integrarea principala deja activa.
3296
+
3297
+
3298
+ if (!activatedByLongPress) {
3299
+
3300
+
3301
+ $("#node-input-expertMode").prop("checked", false);
3302
+
3303
+
3304
+ specialExpertUnlockedState.multiGrid = false;
3305
+
3306
+
3307
+ specialExpertUnlockedState.bessControl = false;
3308
+
3309
+
3310
+ specialExpertUnlockedState.controlExportReactive = false;
3311
+
3312
+
3313
+ specialExpertUnlockedState.scadaServer = false;
3314
+
3315
+
3316
+ specialExpertUnlockedState.influxDb = false;
3317
+
3318
+
3319
+ } else {
3320
+
3321
+
3322
+ specialExpertUnlockedState.influxDb = true;
3323
+
3324
+
3325
+ }
3326
+
3327
+
3328
+ } else {
3329
+
3330
+
3331
+ specialExpertUnlockedState.influxDb = false;
3332
+
3333
+
3334
+ }
3335
+
3336
+
3337
+ specialLongPressActivationMode = "";
3338
+
3339
+
3340
+ toggleMultiGridFields();
3341
+
3342
+
3343
+ persistPayloadSelection(payloadSelectionState, { allowEmptySpecial: true });
3344
+
3345
+
3346
+ });
3347
+
3348
+
3349
+
3350
+ setupSpecialModeLongPress();
3351
+
3352
+
3353
+ toggleMultiGridFields();
3354
+
3355
+
3356
+ },
3357
+
3358
+
3359
+ oneditsave: function () {
3360
+
3361
+
3362
+ const multiGrid = $("#node-input-multiGrid").is(":checked");
3363
+
3364
+
3365
+ const bessControl = $("#node-input-bessControl").is(":checked");
3366
+
3367
+
3368
+ const controlExportReactive = $("#node-input-controlExportReactive").is(":checked");
3369
+
3370
+
3371
+ const scadaServer = $("#node-input-scadaServer").is(":checked");
3372
+
3373
+
3374
+ const influxDb = $("#node-input-influxDb").is(":checked");
3375
+
3376
+
3377
+ const specialMode = getActiveSpecialMode(multiGrid, bessControl, controlExportReactive, scadaServer, influxDb);
3378
+
3379
+
3380
+ const expertMode = $("#node-input-expertMode").is(":checked");
3381
+
3382
+
3383
+ const modeCustomEnabled = !!(specialMode && (customModeEnabledState[specialMode] || expertMode));
3384
+
3385
+
3386
+ let selected = sanitizeForMode(payloadSelectionState, multiGrid, bessControl, controlExportReactive, scadaServer, influxDb, { allowEmptySpecial: !!(specialMode && modeCustomEnabled) });
3387
+
3388
+
3389
+
3390
+ if (specialMode && expertMode) {
3391
+
3392
+
3393
+ customModeEnabledState[specialMode] = true;
3394
+
3395
+
3396
+ customModeSelections[specialMode] = sanitizeCustomModeSelection(selected);
3397
+
3398
+
3399
+ }
3400
+
3401
+
3402
+
3403
+ if (specialMode && customModeEnabledState[specialMode]) {
3404
+
3405
+
3406
+ this.payloadFields = selected.slice();
3407
+
3408
+
3409
+ } else if (specialMode) {
3410
+
3411
+
3412
+ this.payloadFields = getDefaultFieldsForMode(specialMode);
3413
+
3414
+
3415
+ } else {
3416
+
3417
+
3418
+ this.payloadFields = selected.includes("full") ? ["full"] : selected.slice();
3419
+
3420
+
3421
+ }
3422
+
3423
+
3424
+
3425
+ this.expertMode = false;
3426
+
3427
+
3428
+ this.multiGridCustomFields = customModeSelections.multiGrid.slice();
3429
+
3430
+
3431
+ this.bessControlCustomFields = customModeSelections.bessControl.slice();
3432
+
3433
+
3434
+ this.controlExportReactiveCustomFields = customModeSelections.controlExportReactive.slice();
3435
+
3436
+
3437
+ this.scadaServerCustomFields = customModeSelections.scadaServer.slice();
3438
+
3439
+
3440
+ this.influxDbCustomFields = customModeSelections.influxDb.slice();
3441
+
3442
+
3443
+ this.multiGridUseSelectedFields = !!customModeEnabledState.multiGrid;
3444
+
3445
+
3446
+ this.bessControlUseSelectedFields = !!customModeEnabledState.bessControl;
3447
+
3448
+
3449
+ this.controlExportReactiveUseSelectedFields = !!customModeEnabledState.controlExportReactive;
3450
+
3451
+
3452
+ this.scadaServerUseSelectedFields = !!customModeEnabledState.scadaServer;
3453
+
3454
+
3455
+ this.influxDbUseSelectedFields = !!customModeEnabledState.influxDb;
3456
+
3457
+
3458
+ this.influxDb = influxDb;
3459
+
3460
+
3461
+ this.influxMeasurement = String($("#node-input-influxMeasurement").val() || "").trim();
3462
+ const timestepText = String($("#node-input-timestep").val() || "").trim().toLowerCase();
3463
+ this.inputs = timestepText === "off" || timestepText === "0" ? 1 : 0;
3464
+
3465
+
3466
+ this.outputs = getSelectedOutputCount({
3467
+
3468
+
3469
+ multiGrid: multiGrid,
3470
+
3471
+
3472
+ bessControl: bessControl,
3473
+
3474
+
3475
+ controlExportReactive: controlExportReactive,
3476
+
3477
+
3478
+ scadaServer: scadaServer,
3479
+
3480
+
3481
+ influxDb: influxDb,
3482
+
3483
+
3484
+ payloadFields: this.payloadFields
3485
+
3486
+
3487
+ });
3488
+
3489
+
3490
+
3491
+ if (!this.name || !String(this.name).trim()) {
3492
+
3493
+
3494
+ this.name = String($("#node-input-host").val() || "").trim();
3495
+
3496
+
3497
+ $("#node-input-name").val(this.name);
3498
+
3499
+
3500
+ }
3501
+
3502
+
3503
+
3504
+ $("#node-input-payloadFields").val(JSON.stringify(this.payloadFields));
3505
+
3506
+
3507
+ $("#node-input-outputs").val(this.outputs);
3508
+
3509
+
3510
+
3511
+ $("#node-input-host").off(".carloHostSync");
3512
+
3513
+
3514
+ $("#node-input-name").off(".carloName");
3515
+
3516
+
3517
+ $("#node-input-payloadMode").off(".carloPayloadMode");
3518
+
3519
+
3520
+ $("#node-input-expertMode").off(".carloExpert");
3521
+
3522
+
3523
+ $("#node-carlo-gavazzi-select-all").off(".carloToolbar");
3524
+
3525
+
3526
+ $("#node-carlo-gavazzi-clear-all").off(".carloToolbar");
3527
+
3528
+
3529
+ $("#node-carlo-gavazzi-default-values").off(".carloToolbar");
3530
+
3531
+
3532
+ $("#node-input-multiGrid").off(".carloMulti");
3533
+
3534
+
3535
+ $("#node-input-bessControl").off(".carloBess");
3536
+
3537
+
3538
+ $("#node-input-controlExportReactive").off(".carloCER");
3539
+
3540
+
3541
+ $("#node-input-scadaServer").off(".carloScada");
3542
+
3543
+
3544
+ $("#node-input-influxDb").off(".carloInflux");
3545
+
3546
+
3547
+ $("#node-input-multiGrid").off(".carloSpecialLongPress");
3548
+
3549
+
3550
+ $("#node-input-bessControl").off(".carloSpecialLongPress");
3551
+
3552
+
3553
+ $("#node-input-controlExportReactive").off(".carloSpecialLongPress");
3554
+
3555
+
3556
+ $("#node-input-scadaServer").off(".carloSpecialLongPress");
3557
+
3558
+
3559
+ $("#node-input-influxDb").off(".carloSpecialLongPress");
3560
+
3561
+
3562
+ clearSpecialLongPressTimer();
3563
+
3564
+
3565
+ },
3566
+
3567
+
3568
+ oneditcancel: function () {
3569
+
3570
+
3571
+ $("#node-input-host").off(".carloHostSync");
3572
+
3573
+
3574
+ $("#node-input-name").off(".carloName");
3575
+
3576
+
3577
+ $("#node-input-payloadMode").off(".carloPayloadMode");
3578
+
3579
+
3580
+ $("#node-input-expertMode").off(".carloExpert");
3581
+
3582
+
3583
+ $("#node-carlo-gavazzi-select-all").off(".carloToolbar");
3584
+
3585
+
3586
+ $("#node-carlo-gavazzi-clear-all").off(".carloToolbar");
3587
+
3588
+
3589
+ $("#node-carlo-gavazzi-default-values").off(".carloToolbar");
3590
+
3591
+
3592
+ $("#node-input-multiGrid").off(".carloMulti");
3593
+
3594
+
3595
+ $("#node-input-bessControl").off(".carloBess");
3596
+
3597
+
3598
+ $("#node-input-controlExportReactive").off(".carloCER");
3599
+
3600
+
3601
+ $("#node-input-scadaServer").off(".carloScada");
3602
+
3603
+
3604
+ $("#node-input-influxDb").off(".carloInflux");
3605
+
3606
+
3607
+ $("#node-input-multiGrid").off(".carloSpecialLongPress");
3608
+
3609
+
3610
+ $("#node-input-bessControl").off(".carloSpecialLongPress");
3611
+
3612
+
3613
+ $("#node-input-controlExportReactive").off(".carloSpecialLongPress");
3614
+
3615
+
3616
+ $("#node-input-scadaServer").off(".carloSpecialLongPress");
3617
+
3618
+
3619
+ $("#node-input-influxDb").off(".carloSpecialLongPress");
3620
+
3621
+
3622
+ clearSpecialLongPressTimer();
3623
+
3624
+
3625
+ }
3626
+
3627
+
3628
+ });
3629
+
3630
+
3631
+
3632
+ })();
3633
+
3634
+
3635
+ </script>
3636
+
3637
+
3638
+
3639
+ <script type="text/html" data-template-name="carlo-gavazzi">
3640
+ <div class="form-row"><label for="node-input-license"><i class="fa fa-key"></i> License</label><input type="text" id="node-input-license"></div>
3641
+
3642
+
3643
+ <div class="carlo-gavazzi-editor">
3644
+
3645
+
3646
+ <div class="pr-section">
3647
+
3648
+
3649
+ <div class="pr-section-title"><i class="fa fa-plug"></i> Connection</div>
3650
+
3651
+
3652
+ <p class="pr-section-note">Configuratia de citire Modbus TCP pentru meterul Carlo Gavazzi.</p>
3653
+
3654
+
3655
+
3656
+ <div class="pr-grid pr-grid-2">
3657
+
3658
+
3659
+ <div class="form-row">
3660
+
3661
+
3662
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
3663
+
3664
+
3665
+ <input type="text" id="node-input-name" placeholder="192.168.0.110">
3666
+
3667
+
3668
+ </div>
3669
+
3670
+
3671
+
3672
+ <div class="form-row" id="row-meter-id" style="display:none;">
3673
+
3674
+
3675
+ <label for="node-input-meterId"><i class="fa fa-id-badge"></i> Meter ID</label>
3676
+
3677
+
3678
+ <input type="text" id="node-input-meterId" placeholder="meter1">
3679
+
3680
+
3681
+ </div>
3682
+
3683
+
3684
+
3685
+ <div class="form-row">
3686
+
3687
+
3688
+ <label for="node-input-host"><i class="fa fa-globe"></i> Host</label>
3689
+
3690
+
3691
+ <input type="text" id="node-input-host" placeholder="192.168.0.110">
3692
+
3693
+
3694
+ </div>
3695
+
3696
+
3697
+
3698
+ <div class="form-row">
3699
+
3700
+
3701
+ <label for="node-input-port"><i class="fa fa-ellipsis-h"></i> Port</label>
3702
+
3703
+
3704
+ <input type="text" id="node-input-port" placeholder="502">
3705
+
3706
+
3707
+ </div>
3708
+
3709
+
3710
+
3711
+ <div class="form-row">
3712
+
3713
+
3714
+ <label for="node-input-unitId"><i class="fa fa-hashtag"></i> Unit ID</label>
3715
+
3716
+
3717
+ <input type="text" id="node-input-unitId" placeholder="1">
3718
+
3719
+
3720
+ </div>
3721
+
3722
+
3723
+
3724
+ <div class="form-row">
3725
+
3726
+
3727
+ <label for="node-input-timestep"><i class="fa fa-refresh"></i> Poll interval</label>
3728
+
3729
+
3730
+ <input type="text" id="node-input-timestep" placeholder="1000 sau off">
3731
+
3732
+
3733
+ </div>
3734
+
3735
+
3736
+ </div>
3737
+
3738
+
3739
+ </div>
3740
+
3741
+
3742
+
3743
+ <div class="pr-section">
3744
+
3745
+
3746
+ <div class="pr-section-title"><i class="fa fa-filter"></i> Payload</div>
3747
+
3748
+
3749
+ <p class="pr-section-note">Poti citi tot payload-ul sau doar campurile selectate.</p>
3750
+
3751
+
3752
+
3753
+ <div class="form-row">
3754
+
3755
+
3756
+ <label for="node-input-payloadMode"><i class="fa fa-list"></i> Payload mode</label>
3757
+
3758
+
3759
+ <select id="node-input-payloadMode">
3760
+
3761
+
3762
+ <option value="full">Full payload</option>
3763
+
3764
+
3765
+ <option value="selected">Selected fields</option>
3766
+
3767
+
3768
+ </select>
3769
+
3770
+
3771
+ </div>
3772
+
3773
+
3774
+
3775
+ <input type="hidden" id="node-input-payloadFields">
3776
+
3777
+
3778
+ <input type="hidden" id="node-input-outputs">
3779
+
3780
+
3781
+
3782
+ <div class="form-row pr-checkbox-row">
3783
+
3784
+
3785
+ <label for="node-input-multiGrid"><i class="fa fa-sitemap"></i> Multi-grid</label>
3786
+
3787
+
3788
+ <input type="checkbox" id="node-input-multiGrid">
3789
+
3790
+
3791
+ <span class="pr-inline-note">Transforma iesirea intr-un payload compact pentru agregare in <code>multi-grid</code>.</span>
3792
+
3793
+
3794
+ </div>
3795
+
3796
+
3797
+
3798
+ <div class="form-row pr-checkbox-row">
3799
+
3800
+
3801
+ <label for="node-input-bessControl"><i class="fa fa-link"></i> BESS control</label>
3802
+
3803
+
3804
+ <input type="checkbox" id="node-input-bessControl">
3805
+
3806
+
3807
+ <span class="pr-inline-note">Transforma iesirea intr-un payload compact pentru <code>bess-control</code>.</span>
3808
+
3809
+
3810
+ </div>
3811
+
3812
+
3813
+
3814
+ <div class="form-row pr-checkbox-row">
3815
+
3816
+
3817
+ <label for="node-input-controlExportReactive"><i class="fa fa-bolt"></i> Control export/reactive</label>
3818
+
3819
+
3820
+ <input type="checkbox" id="node-input-controlExportReactive">
3821
+
3822
+
3823
+ <span class="pr-inline-note">Transforma iesirea intr-un payload compact cu putere activa si reactiva pentru <code>control-export</code> si <code>control-reactive</code>.</span>
3824
+
3825
+
3826
+ </div>
3827
+
3828
+
3829
+
3830
+ <div class="form-row pr-checkbox-row">
3831
+
3832
+
3833
+ <label for="node-input-scadaServer"><i class="fa fa-server"></i> SCADA server</label>
3834
+
3835
+
3836
+ <input type="checkbox" id="node-input-scadaServer">
3837
+
3838
+
3839
+ <span class="pr-inline-note">Transforma iesirea intr-un payload compact pentru nodul <code>scada-server</code>.</span>
3840
+
3841
+
3842
+ </div>
3843
+
3844
+
3845
+
3846
+ <div class="form-row pr-checkbox-row">
3847
+
3848
+
3849
+ <label for="node-input-influxDb"><i class="fa fa-database"></i> InfluxDB</label>
3850
+
3851
+
3852
+ <input type="checkbox" id="node-input-influxDb">
3853
+
3854
+
3855
+ <span class="pr-inline-note">Grupeaza valorile meterului in <code>msg.influx</code> pentru nodul <code>adt-influxdb</code>.</span>
3856
+
3857
+
3858
+ </div>
3859
+
3860
+
3861
+
3862
+ <div class="form-row" id="row-influx-measurement" style="display:none;">
3863
+
3864
+
3865
+ <label for="node-input-influxMeasurement"><i class="fa fa-line-chart"></i> Measurement</label>
3866
+
3867
+
3868
+ <input type="text" id="node-input-influxMeasurement" placeholder="Grid Meter">
3869
+
3870
+
3871
+ </div>
3872
+ <div class="form-row" id="row-influx-node" style="display:none;">
3873
+ <label for="node-input-influxNode"><i class="fa fa-plug"></i> Nod InfluxDB</label>
3874
+ <select id="node-input-influxNode"></select>
3875
+ </div>
3876
+
3877
+
3878
+
3879
+ <div class="form-row pr-checkbox-row" id="row-expert-mode" style="display:none;">
3880
+
3881
+
3882
+ <label for="node-input-expertMode"><i class="fa fa-wrench"></i> Custom fields</label>
3883
+
3884
+
3885
+ <input type="checkbox" id="node-input-expertMode">
3886
+
3887
+
3888
+ <span class="pr-inline-note">Activeaza editarea manuala a campurilor presetate.</span>
3889
+
3890
+
3891
+ </div>
3892
+
3893
+
3894
+
3895
+ <div id="row-carlo-gavazzi-field-list" style="display:none;">
3896
+
3897
+
3898
+ <div class="pr-toolbar">
3899
+
3900
+
3901
+ <a href="#" class="button" id="node-carlo-gavazzi-select-all"><i class="fa fa-check-square-o"></i> Select all</a>
3902
+
3903
+
3904
+ <a href="#" class="button" id="node-carlo-gavazzi-clear-all"><i class="fa fa-square-o"></i> Clear all</a>
3905
+
3906
+
3907
+ <a href="#" class="button" id="node-carlo-gavazzi-default-values" style="display:none;"><i class="fa fa-undo"></i> Default values</a>
3908
+
3909
+
3910
+ </div>
3911
+
3912
+
3913
+
3914
+ <div id="node-carlo-gavazzi-field-list-container" class="pr-field-list"></div>
3915
+
3916
+
3917
+ </div>
3918
+
3919
+
3920
+
3921
+ </div>
3922
+
3923
+
3924
+ </div>
3925
+
3926
+
3927
+ </script>
3928
+
3929
+
3930
+
3931
+ <script type="text/html" data-help-name="carlo-gavazzi">
3932
+
3933
+
3934
+ <p>
3935
+
3936
+
3937
+ Nodul <b>carlo-gavazzi</b> citeste un smart meter Carlo Gavazzi prin Modbus TCP si emite valorile
3938
+
3939
+
3940
+ masurate in Node-RED. Citirea se face automat la intervalul setat in <b>Poll interval</b>. Valoarea <code>off</code> sau <code>0</code> opreste citirea periodica si activeaza citirea la trigger pe intrare.
3941
+
3942
+
3943
+ </p>
3944
+
3945
+
3946
+
3947
+ <h3>Conexiune</h3>
3948
+
3949
+
3950
+ <ul>
3951
+
3952
+
3953
+ <li><b>Name</b> este numele afisat in flow. Daca ramane gol, nodul foloseste automat IP-ul.</li>
3954
+
3955
+
3956
+ <li><b>Host</b> este adresa IP a meterului sau a gateway-ului Modbus TCP.</li>
3957
+
3958
+
3959
+ <li><b>Port</b> este portul Modbus TCP, de obicei <code>502</code>.</li>
3960
+
3961
+
3962
+ <li><b>Unit ID</b> este adresa Modbus a meterului.</li>
3963
+
3964
+
3965
+ <li><b>Poll interval</b> este perioada dintre doua citiri succesive; <code>off</code> sau <code>0</code> activeaza citirea manuala pe intrare.</li>
3966
+
3967
+
3968
+ </ul>
3969
+
3970
+
3971
+
3972
+ <h3>Valori citite</h3>
3973
+
3974
+
3975
+ <p>
3976
+
3977
+
3978
+ Nodul citeste tensiuni, curenti, putere activa, putere aparenta, putere reactiva,
3979
+
3980
+
3981
+ factor de putere, frecventa, ordine faze si contoare de energie.
3982
+
3983
+
3984
+ </p>
3985
+
3986
+
3987
+
3988
+ <ul>
3989
+
3990
+
3991
+ <li><code>summary.power.total_w</code> si <code>summary.power.l1_w/l2_w/l3_w</code> pentru putere activa.</li>
3992
+
3993
+
3994
+ <li><code>summary.reactive.total_var</code> si <code>summary.reactive.l1_var/l2_var/l3_var</code> pentru putere reactiva.</li>
3995
+
3996
+
3997
+ <li><code>summary.voltage.*</code> pentru tensiuni faza-nul si faza-faza.</li>
3998
+
3999
+
4000
+ <li><code>summary.current.*</code> pentru curenti.</li>
4001
+
4002
+
4003
+ <li><code>summary.energy.*</code> pentru energii import/export si tarife.</li>
4004
+
4005
+
4006
+ </ul>
4007
+
4008
+
4009
+
4010
+ <h3>Payload mode</h3>
4011
+
4012
+
4013
+ <p>
4014
+
4015
+
4016
+ In <b>Full payload</b>, nodul trimite tot obiectul citit de la meter.
4017
+
4018
+
4019
+ In <b>Selected fields</b>, nodul trimite doar campurile selectate.
4020
+
4021
+
4022
+ </p>
4023
+
4024
+
4025
+
4026
+ <p>
4027
+
4028
+
4029
+ In modul normal, daca este selectat un singur camp, <code>msg.topic</code> contine numele valorii,
4030
+
4031
+
4032
+ iar <code>msg.payload</code> contine valoarea. Daca sunt selectate mai multe campuri, nodul emite
4033
+
4034
+
4035
+ cate un mesaj pentru fiecare camp selectat.
4036
+
4037
+
4038
+ </p>
4039
+
4040
+
4041
+
4042
+ <pre>{
4043
+
4044
+
4045
+ "topic": "Putere totala",
4046
+
4047
+
4048
+ "payload": -850,
4049
+
4050
+
4051
+ "payload_field": "summary.power.total_w"
4052
+
4053
+
4054
+ }</pre>
4055
+
4056
+
4057
+
4058
+ <p>
4059
+
4060
+
4061
+ In fiecare mesaj, <code>msg.carloGavazzi</code> contine obiectul complet citit de la meter, util pentru
4062
+
4063
+
4064
+ diagnostic sau pentru alte transformari.
4065
+
4066
+
4067
+ </p>
4068
+
4069
+
4070
+
4071
+ <h3>Control export/reactive</h3>
4072
+
4073
+
4074
+ <p>
4075
+
4076
+
4077
+ Cand este activ <b>Control export/reactive</b>, nodul emite un singur payload compact compatibil cu
4078
+
4079
+
4080
+ <code>control-export</code> si <code>control-reactive</code>. In acest mod, <code>msg.topic</code>
4081
+
4082
+
4083
+ devine <b>Meter ID</b>.
4084
+
4085
+
4086
+ </p>
4087
+
4088
+
4089
+
4090
+ <pre>{
4091
+
4092
+
4093
+ "topic": "meter1",
4094
+
4095
+
4096
+ "meter_id": "meter1",
4097
+
4098
+
4099
+ "payload": {
4100
+
4101
+
4102
+ "power_w": -850,
4103
+
4104
+
4105
+ "power_l1_w": -300,
4106
+
4107
+
4108
+ "power_l2_w": -280,
4109
+
4110
+
4111
+ "power_l3_w": -270,
4112
+
4113
+
4114
+ "reactive_total_var": 420,
4115
+
4116
+
4117
+ "reactive_l1_var": 120,
4118
+
4119
+
4120
+ "reactive_l2_var": 150,
4121
+
4122
+
4123
+ "reactive_l3_var": 150
4124
+
4125
+
4126
+ }
4127
+
4128
+
4129
+ }</pre>
4130
+
4131
+
4132
+
4133
+ <p>
4134
+
4135
+
4136
+ <code>control-export</code> foloseste campurile active in W, iar <code>control-reactive</code> foloseste
4137
+
4138
+
4139
+ campurile reactive in VAr. Pentru <code>control-reactive</code> sunt necesare totalul si valorile pe faze.
4140
+
4141
+
4142
+ </p>
4143
+
4144
+
4145
+
4146
+ <h3>Multi-grid</h3>
4147
+
4148
+
4149
+ <p>
4150
+
4151
+
4152
+ Cand este activ <b>Multi-grid</b>, nodul emite un payload compact pentru agregare in <code>multi-grid</code>.
4153
+
4154
+
4155
+ <code>msg.topic</code> si <code>msg.meter_id</code> contin ID-ul meterului.
4156
+
4157
+
4158
+ </p>
4159
+
4160
+
4161
+
4162
+ <h3>BESS control</h3>
4163
+
4164
+
4165
+ <p>
4166
+
4167
+
4168
+ Cand este activ <b>BESS control</b>, nodul emite campurile active necesare pentru <code>bess-control</code>,
4169
+
4170
+
4171
+ de exemplu <code>power_w</code> si puterile pe faze.
4172
+
4173
+
4174
+ </p>
4175
+
4176
+
4177
+
4178
+ <h3>SCADA server</h3>
4179
+
4180
+
4181
+ <p>
4182
+
4183
+
4184
+ Cand este activ <b>SCADA server</b>, nodul foloseste chei compacte potrivite pentru maparea implicita din
4185
+
4186
+
4187
+ <code>scada-server</code>, de exemplu <code>active_power_w</code>, <code>reactive_power_var</code>,
4188
+
4189
+
4190
+ <code>frequency_hz</code> si tensiunile linie-la-linie.
4191
+
4192
+
4193
+ </p>
4194
+
4195
+ <h3>InfluxDB</h3>
4196
+
4197
+
4198
+ <p>
4199
+
4200
+
4201
+ Cand este activ <b>InfluxDB</b>, nodul emite un singur mesaj agregat per citire, cu
4202
+
4203
+
4204
+ <code>msg.influx.measurement</code>, <code>msg.influx.tags</code>, <code>msg.influx.fields</code> si
4205
+
4206
+
4207
+ <code>msg.influx.timestamp</code>, compatibil direct cu nodul <code>adt-influxdb</code>.
4208
+
4209
+
4210
+ </p>
4211
+
4212
+
4213
+ <h3>Moduri speciale</h3>
4214
+
4215
+
4216
+ <p>
4217
+
4218
+
4219
+ Poti activa o singura integrare principala dintre <b>Multi-grid</b>, <b>BESS control</b>, <b>Control export/reactive</b> si <b>SCADA server</b>. <b>InfluxDB</b> poate fi activat simultan cu oricare dintre ele; maximum doua optiuni pot ramane active.
4220
+
4221
+
4222
+ Activeaza un singur mod special pentru o iesire clara si compatibila cu nodul urmator.
4223
+
4224
+
4225
+ </p>
4226
+
4227
+
4228
+
4229
+ <h3>Status</h3>
4230
+
4231
+
4232
+ <ul>
4233
+
4234
+
4235
+ <li><b>verde</b> inseamna citire reusita.</li>
4236
+
4237
+
4238
+ <li><b>galben</b> inseamna citire in curs.</li>
4239
+
4240
+
4241
+ <li><b>rosu</b> inseamna eroare de conexiune, raspuns Modbus invalid sau timeout.</li>
4242
+
4243
+
4244
+ </ul>
4245
+
4246
+
4247
+
4248
+ <h3>Recomandari practice</h3>
4249
+
4250
+
4251
+ <ul>
4252
+
4253
+
4254
+ <li>Pentru <code>control-export</code> si <code>control-reactive</code>, foloseste modul <b>Control export/reactive</b>.</li>
4255
+
4256
+
4257
+ <li>Foloseste un <b>Meter ID</b> stabil daca mai multe metere intra in acelasi flow.</li>
4258
+
4259
+
4260
+ <li>Pastreaza poll intervalul suficient de rapid pentru control, dar nu mai rapid decat poate raspunde meterul.</li>
4261
+
4262
+
4263
+ <li>Daca apar valori inversate, verifica sensul montajului transformatoarelor de curent si conventia de semn in nodurile de control.</li>
4264
+
4265
+
4266
+ </ul>
4267
+
4268
+
4269
+ <h3>Referinta completa parametri</h3>
4270
+
4271
+ <ul>
4272
+
4273
+ <li><code>host</code>, <code>port</code>, <code>unitId</code>: conexiunea Modbus TCP catre contor.</li>
4274
+
4275
+ <li><code>timestep</code>: intervalul de poll in milisecunde; <code>off</code> sau <code>0</code> opreste poll-ul automat si citeste doar la trigger pe intrare.</li>
4276
+
4277
+ <li><code>meterId</code>: identificator stabil emis in <code>msg.topic</code>, <code>msg.meter_id</code> si <code>msg.source_id</code>.</li>
4278
+
4279
+ <li><code>payloadMode</code>: <code>full</code> trimite toate valorile, <code>selected</code> trimite doar <code>payloadFields</code>.</li>
4280
+
4281
+ <li><code>payloadFields</code>: lista campurilor selectate pentru payload normal.</li>
4282
+
4283
+ <li><code>multiGrid</code>, <code>bessControl</code>, <code>controlExportReactive</code>, <code>scadaServer</code>, <code>influxDb</code>: o integrare principala, optional impreuna cu InfluxDB.</li>
4284
+
4285
+ <li><code>influxMeasurement</code>: measurement-ul folosit in <code>msg.influx.measurement</code>.</li>
4286
+
4287
+ <li><code>multiGridCustomFields</code>, <code>bessControlCustomFields</code>, <code>controlExportReactiveCustomFields</code>, <code>scadaServerCustomFields</code>, <code>influxDbCustomFields</code>: selectiile salvate pentru fiecare preset.</li>
4288
+
4289
+ <li><code>multiGridUseSelectedFields</code>, <code>bessControlUseSelectedFields</code>, <code>controlExportReactiveUseSelectedFields</code>, <code>scadaServerUseSelectedFields</code>, <code>influxDbUseSelectedFields</code>: forteaza presetul sa foloseasca lista custom in locul valorilor implicite.</li>
4290
+
4291
+ <li><code>outputs</code>: numarul de iesiri calculat de editor in functie de modul de payload/debug.</li>
4292
+
4293
+ </ul>
4294
+
4295
+
4296
+ <h3>Exemplu pentru control-export/reactive</h3>
4297
+
4298
+ <pre>{
4299
+ "topic": "grid-main",
4300
+ "meter_id": "grid-main",
4301
+ "source_id": "grid-main",
4302
+ "payload": {
4303
+ "power_w": -1200,
4304
+ "power_l1_w": -350,
4305
+ "power_l2_w": -420,
4306
+ "power_l3_w": -430,
4307
+ "reactive_total_var": 180
4308
+ },
4309
+ "timestamp_ms": 1776692400000
4310
+ }</pre>
4311
+
4312
+
4313
+ </script>
4314
+
4315
+
4316
+
4317
+ <script type="text/html" data-help-name="carlo-gavazzi-legacy-disabled">
4318
+
4319
+
4320
+ <p>Node pentru citirea unui smart meter Carlo Gavazzi prin Modbus TCP.</p>
4321
+
4322
+
4323
+ <p>Nod legacy. Foloseste help-ul nodului carlo-gavazzi.</p>
4324
+
4325
+
4326
+ </script>
4327
+