@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,711 @@
1
+ const AC_OPTIONS_COMMON = [
2
+
3
+ { value: "summary.ac.power_w", label: "Putere AC (W)" },
4
+
5
+ { value: "summary.ac.frequency_hz", label: "Frecvență (Hz)" },
6
+
7
+ { value: "summary.ac.apparent_power_va", label: "Putere aparentă (VA)" },
8
+
9
+ { value: "summary.ac.reactive_power_var", label: "Putere reactivă (var)" }
10
+
11
+ ];
12
+
13
+
14
+ const AC_OPTIONS_SINGLE_PHASE = [
15
+
16
+ { value: "summary.ac.current_total_a", label: "Curent total (A)" },
17
+
18
+ { value: "summary.ac.current_l1_a", label: "Curent L1 (A)" },
19
+
20
+ { value: "summary.ac.voltage_l1_v", label: "Tensiune L1 (V)" }
21
+
22
+ ];
23
+
24
+
25
+ const AC_OPTIONS_THREE_PHASE = [
26
+
27
+ { value: "summary.ac.current_total_a", label: "Curent total (A)" },
28
+
29
+ { value: "summary.ac.current_l1_a", label: "Curent L1 (A)" },
30
+
31
+ { value: "summary.ac.current_l2_a", label: "Curent L2 (A)" },
32
+
33
+ { value: "summary.ac.current_l3_a", label: "Curent L3 (A)" },
34
+
35
+ { value: "summary.ac.voltage_ll_ab_v", label: "Tensiune AB (V)" },
36
+
37
+ { value: "summary.ac.voltage_ll_bc_v", label: "Tensiune BC (V)" },
38
+
39
+ { value: "summary.ac.voltage_ll_ca_v", label: "Tensiune CA (V)" },
40
+
41
+ { value: "summary.ac.voltage_l1_v", label: "Tensiune L1 (V)" },
42
+
43
+ { value: "summary.ac.voltage_l2_v", label: "Tensiune L2 (V)" },
44
+
45
+ { value: "summary.ac.voltage_l3_v", label: "Tensiune L3 (V)" }
46
+
47
+ ];
48
+
49
+
50
+ const PAYLOAD_OPTION_GROUPS = {
51
+
52
+ dcGeneral: [
53
+
54
+ { value: "summary.dc.dc_total_power_w", label: "Putere DC totală (W)" },
55
+
56
+ { value: "summary.dc.module_count", label: "Număr module/stringuri DC (brut)" },
57
+
58
+ { value: "summary.dc.global_event", label: "Eveniment DC global" }
59
+
60
+ ],
61
+
62
+
63
+ device: [
64
+
65
+ { value: "summary.common.manufacturer", label: "Producător" },
66
+
67
+ { value: "summary.common.model", label: "Model" },
68
+
69
+ { value: "summary.common.options", label: "Opțiuni" },
70
+
71
+ { value: "summary.common.version", label: "Versiune" },
72
+
73
+ { value: "summary.common.serial", label: "Serie" },
74
+
75
+ { value: "summary.common.device_address", label: "Adresă device" }
76
+
77
+ ]
78
+
79
+ };
80
+
81
+
82
+ const INVERTER_PROFILES = {
83
+
84
+ auto: {
85
+
86
+ key: "auto",
87
+
88
+ label: "Auto Detect",
89
+
90
+ manufacturer: null,
91
+
92
+ family: "generic",
93
+
94
+ fallbackMpptCount: 4,
95
+
96
+ fallbackPhaseMode: "unknown",
97
+
98
+ includeAC: true,
99
+
100
+ includeDCGeneral: true,
101
+
102
+ includeDevice: true
103
+
104
+ },
105
+
106
+
107
+ fronius_verto: {
108
+
109
+ key: "fronius_verto",
110
+
111
+ label: "Fronius Verto",
112
+
113
+ manufacturer: "fronius",
114
+
115
+ family: "verto",
116
+
117
+ fallbackMpptCount: 4,
118
+
119
+ fallbackPhaseMode: "three_phase",
120
+
121
+ includeAC: true,
122
+
123
+ includeDCGeneral: true,
124
+
125
+ includeDevice: true
126
+
127
+ },
128
+
129
+
130
+ fronius_symo: {
131
+
132
+ key: "fronius_symo",
133
+
134
+ label: "Fronius Symo",
135
+
136
+ manufacturer: "fronius",
137
+
138
+ family: "symo",
139
+
140
+ fallbackMpptCount: 2,
141
+
142
+ fallbackPhaseMode: "three_phase",
143
+
144
+ includeAC: true,
145
+
146
+ includeDCGeneral: true,
147
+
148
+ includeDevice: true
149
+
150
+ },
151
+
152
+
153
+ fronius_primo: {
154
+
155
+ key: "fronius_primo",
156
+
157
+ label: "Fronius Primo",
158
+
159
+ manufacturer: "fronius",
160
+
161
+ family: "primo",
162
+
163
+ fallbackMpptCount: 2,
164
+
165
+ fallbackPhaseMode: "single_phase",
166
+
167
+ includeAC: true,
168
+
169
+ includeDCGeneral: true,
170
+
171
+ includeDevice: true
172
+
173
+ },
174
+
175
+
176
+ fronius_eco: {
177
+
178
+ key: "fronius_eco",
179
+
180
+ label: "Fronius Eco",
181
+
182
+ manufacturer: "fronius",
183
+
184
+ family: "eco",
185
+
186
+ fallbackMpptCount: 1,
187
+
188
+ fallbackPhaseMode: "three_phase",
189
+
190
+ includeAC: true,
191
+
192
+ includeDCGeneral: true,
193
+
194
+ includeDevice: true
195
+
196
+ },
197
+
198
+
199
+ fronius_tauro: {
200
+
201
+ key: "fronius_tauro",
202
+
203
+ label: "Fronius Tauro",
204
+
205
+ manufacturer: "fronius",
206
+
207
+ family: "tauro",
208
+
209
+ fallbackMpptCount: 3,
210
+
211
+ fallbackPhaseMode: "three_phase",
212
+
213
+ includeAC: true,
214
+
215
+ includeDCGeneral: true,
216
+
217
+ includeDevice: true
218
+
219
+ },
220
+
221
+
222
+ fronius_tauro_eco: {
223
+
224
+ key: "fronius_tauro_eco",
225
+
226
+ label: "Fronius Tauro Eco",
227
+
228
+ manufacturer: "fronius",
229
+
230
+ family: "tauro_eco",
231
+
232
+ fallbackMpptCount: 1,
233
+
234
+ fallbackPhaseMode: "three_phase",
235
+
236
+ includeAC: true,
237
+
238
+ includeDCGeneral: true,
239
+
240
+ includeDevice: true
241
+
242
+ }
243
+
244
+ };
245
+
246
+
247
+ function buildMpptOptions(mpptIndex) {
248
+
249
+ return [
250
+
251
+ { value: `summary.dc.mppts.${mpptIndex}.dc_voltage_v`, label: "Tensiune (V)" },
252
+
253
+ { value: `summary.dc.mppts.${mpptIndex}.dc_current_a`, label: "Curent (A)" },
254
+
255
+ { value: `summary.dc.mppts.${mpptIndex}.dc_power_w`, label: "Putere (W)" },
256
+
257
+ { value: `summary.dc.mppts.${mpptIndex}.dc_energy_wh`, label: "Energie (Wh)" }
258
+
259
+ ];
260
+
261
+ }
262
+
263
+
264
+ function buildAcOptions(phaseMode) {
265
+
266
+ const common = AC_OPTIONS_COMMON.slice();
267
+
268
+
269
+ if (phaseMode === "single_phase") {
270
+
271
+ return common.concat(AC_OPTIONS_SINGLE_PHASE);
272
+
273
+ }
274
+
275
+
276
+ if (phaseMode === "three_phase") {
277
+
278
+ return common.concat(AC_OPTIONS_THREE_PHASE);
279
+
280
+ }
281
+
282
+
283
+ const merged = [];
284
+
285
+ const seen = new Set();
286
+
287
+
288
+ common
289
+
290
+ .concat(AC_OPTIONS_SINGLE_PHASE)
291
+
292
+ .concat(AC_OPTIONS_THREE_PHASE)
293
+
294
+ .forEach((item) => {
295
+
296
+ if (!seen.has(item.value)) {
297
+
298
+ seen.add(item.value);
299
+
300
+ merged.push(item);
301
+
302
+ }
303
+
304
+ });
305
+
306
+
307
+ return merged;
308
+
309
+ }
310
+
311
+
312
+ function normalizeText(value) {
313
+
314
+ return String(value || "")
315
+
316
+ .toLowerCase()
317
+
318
+ .replace(/[^a-z0-9]+/g, " ")
319
+
320
+ .trim();
321
+
322
+ }
323
+
324
+
325
+ function hasNumericValue(value) {
326
+
327
+ return Number.isFinite(value);
328
+
329
+ }
330
+
331
+
332
+ function getDetectedMpptCount(summary) {
333
+
334
+ if (!summary || !summary.dc) {
335
+
336
+ return null;
337
+
338
+ }
339
+
340
+
341
+ if (Number.isFinite(summary.dc.module_count) && summary.dc.module_count > 0) {
342
+
343
+ return summary.dc.module_count;
344
+
345
+ }
346
+
347
+
348
+ if (Array.isArray(summary.dc.mppts) && summary.dc.mppts.length > 0) {
349
+
350
+ return summary.dc.mppts.length;
351
+
352
+ }
353
+
354
+
355
+ return null;
356
+
357
+ }
358
+
359
+
360
+ function detectPhaseMode(summary) {
361
+
362
+ const ac = summary && summary.ac ? summary.ac : null;
363
+
364
+
365
+ if (!ac) {
366
+
367
+ return "unknown";
368
+
369
+ }
370
+
371
+
372
+ const hasThreePhaseEvidence =
373
+
374
+ hasNumericValue(ac.current_l2_a) ||
375
+
376
+ hasNumericValue(ac.current_l3_a) ||
377
+
378
+ hasNumericValue(ac.voltage_l2_v) ||
379
+
380
+ hasNumericValue(ac.voltage_l3_v) ||
381
+
382
+ hasNumericValue(ac.voltage_ll_ab_v) ||
383
+
384
+ hasNumericValue(ac.voltage_ll_bc_v) ||
385
+
386
+ hasNumericValue(ac.voltage_ll_ca_v);
387
+
388
+
389
+ if (hasThreePhaseEvidence) {
390
+
391
+ return "three_phase";
392
+
393
+ }
394
+
395
+
396
+ const hasSinglePhaseEvidence =
397
+
398
+ hasNumericValue(ac.current_l1_a) ||
399
+
400
+ hasNumericValue(ac.voltage_l1_v) ||
401
+
402
+ hasNumericValue(ac.current_total_a);
403
+
404
+
405
+ if (hasSinglePhaseEvidence) {
406
+
407
+ return "single_phase";
408
+
409
+ }
410
+
411
+
412
+ return "unknown";
413
+
414
+ }
415
+
416
+
417
+ function detectFroniusProfileKey(combinedText) {
418
+
419
+ if (/\btauro\s+eco\b/i.test(combinedText) || /\btauro[-\s]*eco\b/i.test(combinedText)) {
420
+
421
+ return "fronius_tauro_eco";
422
+
423
+ }
424
+
425
+
426
+ if (/\btauro\b/i.test(combinedText)) {
427
+
428
+ return "fronius_tauro";
429
+
430
+ }
431
+
432
+
433
+ if (/\bverto\b/i.test(combinedText)) {
434
+
435
+ return "fronius_verto";
436
+
437
+ }
438
+
439
+
440
+ if (/\bsymo\b/i.test(combinedText) || /\bsnap\s?inverter\b/i.test(combinedText)) {
441
+
442
+ return "fronius_symo";
443
+
444
+ }
445
+
446
+
447
+ if (/\bprimo\b/i.test(combinedText)) {
448
+
449
+ return "fronius_primo";
450
+
451
+ }
452
+
453
+
454
+ if (/\beco\b/i.test(combinedText)) {
455
+
456
+ return "fronius_eco";
457
+
458
+ }
459
+
460
+
461
+ return null;
462
+
463
+ }
464
+
465
+
466
+ function buildDetectionResult(profile, phaseMode, detectedMpptCount, detectionSource) {
467
+
468
+ return {
469
+
470
+ profile_key: profile.key,
471
+
472
+ profile_label: profile.label,
473
+
474
+ manufacturer: profile.manufacturer,
475
+
476
+ family: profile.family,
477
+
478
+ phase_mode: phaseMode !== "unknown" ? phaseMode : profile.fallbackPhaseMode,
479
+
480
+ mppt_count:
481
+
482
+ Number.isFinite(detectedMpptCount) && detectedMpptCount > 0
483
+
484
+ ? detectedMpptCount
485
+
486
+ : profile.fallbackMpptCount,
487
+
488
+ detection_source: detectionSource,
489
+
490
+ detected_mppt_count: detectedMpptCount
491
+
492
+ };
493
+
494
+ }
495
+
496
+
497
+ function detectInverterProfile(summary) {
498
+
499
+ const common = summary && summary.common ? summary.common : {};
500
+
501
+ const manufacturer = normalizeText(common.manufacturer);
502
+
503
+ const model = normalizeText(common.model);
504
+
505
+ const options = normalizeText(common.options);
506
+
507
+ const version = normalizeText(common.version);
508
+
509
+ const combined = `${manufacturer} ${model} ${options} ${version}`.trim();
510
+
511
+
512
+ const phaseMode = detectPhaseMode(summary);
513
+
514
+ const detectedMpptCount = getDetectedMpptCount(summary);
515
+
516
+
517
+ if (manufacturer.includes("fronius")) {
518
+
519
+ const matchedProfileKey = detectFroniusProfileKey(combined);
520
+
521
+
522
+ if (matchedProfileKey) {
523
+
524
+ return buildDetectionResult(
525
+
526
+ INVERTER_PROFILES[matchedProfileKey],
527
+
528
+ phaseMode,
529
+
530
+ detectedMpptCount,
531
+
532
+ "manufacturer_model+ac+dc"
533
+
534
+ );
535
+
536
+ }
537
+
538
+
539
+ if (phaseMode === "single_phase" && detectedMpptCount === 2) {
540
+
541
+ return buildDetectionResult(
542
+
543
+ INVERTER_PROFILES.fronius_primo,
544
+
545
+ "single_phase",
546
+
547
+ detectedMpptCount,
548
+
549
+ "ac+dc_inference"
550
+
551
+ );
552
+
553
+ }
554
+
555
+
556
+ if (phaseMode === "three_phase" && detectedMpptCount === 4) {
557
+
558
+ return buildDetectionResult(
559
+
560
+ INVERTER_PROFILES.fronius_verto,
561
+
562
+ "three_phase",
563
+
564
+ detectedMpptCount,
565
+
566
+ "ac+dc_inference"
567
+
568
+ );
569
+
570
+ }
571
+
572
+
573
+ if (phaseMode === "three_phase" && detectedMpptCount === 3) {
574
+
575
+ return buildDetectionResult(
576
+
577
+ INVERTER_PROFILES.fronius_tauro,
578
+
579
+ "three_phase",
580
+
581
+ detectedMpptCount,
582
+
583
+ "ac+dc_inference"
584
+
585
+ );
586
+
587
+ }
588
+
589
+
590
+ if (phaseMode === "three_phase" && detectedMpptCount === 2) {
591
+
592
+ return buildDetectionResult(
593
+
594
+ INVERTER_PROFILES.fronius_symo,
595
+
596
+ "three_phase",
597
+
598
+ detectedMpptCount,
599
+
600
+ "ac+dc_inference"
601
+
602
+ );
603
+
604
+ }
605
+
606
+
607
+ if (phaseMode === "three_phase" && detectedMpptCount === 1) {
608
+
609
+ return buildDetectionResult(
610
+
611
+ INVERTER_PROFILES.fronius_eco,
612
+
613
+ "three_phase",
614
+
615
+ detectedMpptCount,
616
+
617
+ "ac+dc_inference"
618
+
619
+ );
620
+
621
+ }
622
+
623
+ }
624
+
625
+
626
+ return {
627
+
628
+ profile_key: "auto",
629
+
630
+ profile_label: INVERTER_PROFILES.auto.label,
631
+
632
+ manufacturer: manufacturer || null,
633
+
634
+ family: "generic",
635
+
636
+ phase_mode: phaseMode,
637
+
638
+ mppt_count:
639
+
640
+ Number.isFinite(detectedMpptCount) && detectedMpptCount > 0
641
+
642
+ ? detectedMpptCount
643
+
644
+ : INVERTER_PROFILES.auto.fallbackMpptCount,
645
+
646
+ detection_source: combined ? "fallback_generic" : "fallback_no_identity",
647
+
648
+ detected_mppt_count: detectedMpptCount
649
+
650
+ };
651
+
652
+ }
653
+
654
+
655
+ function resolveProfile(profileKey, detectedMpptCount, detectedPhaseMode) {
656
+
657
+ const profile = INVERTER_PROFILES[profileKey] || INVERTER_PROFILES.auto;
658
+
659
+
660
+ const resolvedMpptCount =
661
+
662
+ Number.isFinite(detectedMpptCount) && detectedMpptCount > 0
663
+
664
+ ? detectedMpptCount
665
+
666
+ : profile.fallbackMpptCount;
667
+
668
+
669
+ const resolvedPhaseMode =
670
+
671
+ detectedPhaseMode && detectedPhaseMode !== "unknown"
672
+
673
+ ? detectedPhaseMode
674
+
675
+ : profile.fallbackPhaseMode;
676
+
677
+
678
+ return {
679
+
680
+ ...profile,
681
+
682
+ resolvedMpptCount,
683
+
684
+ resolvedPhaseMode
685
+
686
+ };
687
+
688
+ }
689
+
690
+
691
+ module.exports = {
692
+
693
+ PAYLOAD_OPTION_GROUPS,
694
+
695
+ INVERTER_PROFILES,
696
+
697
+ buildMpptOptions,
698
+
699
+ buildAcOptions,
700
+
701
+ normalizeText,
702
+
703
+ getDetectedMpptCount,
704
+
705
+ detectPhaseMode,
706
+
707
+ detectInverterProfile,
708
+
709
+ resolveProfile
710
+
711
+ };