@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.
- package/NOTICE +56 -0
- package/PROPRIETARY-LICENSE.txt +157 -0
- package/README.md +105 -0
- package/TERMS-AND-CONDITIONS.md +311 -0
- package/advantech-read/advantech-read.html +775 -0
- package/advantech-read/advantech-read.js +449 -0
- package/advantech-write/advantech-write.html +413 -0
- package/advantech-write/advantech-write.js +338 -0
- package/bess-control/bess-control.html +569 -0
- package/bess-control/bess-control.js +541 -0
- package/bess-control/lib/allocation.js +149 -0
- package/bess-control/lib/batteries.js +86 -0
- package/bess-control/lib/helpers.js +157 -0
- package/bess-control/lib/messages.js +131 -0
- package/bess-control/lib/runtime.js +156 -0
- package/carlo-gavazzi/carlo-gavazzi.html +4327 -0
- package/carlo-gavazzi/carlo-gavazzi.js +3081 -0
- package/control-export/control-export.html +3644 -0
- package/control-export/control-export.js +2192 -0
- package/control-reactive/control-reactive.html +3136 -0
- package/control-reactive/control-reactive.js +2124 -0
- package/fronius-emulator/README.md +258 -0
- package/fronius-emulator/fronius-emulator.html +170 -0
- package/fronius-emulator/fronius-emulator.js +520 -0
- package/fronius-emulator/lib/binary-codec.js +65 -0
- package/fronius-emulator/lib/fronius-register-map.js +185 -0
- package/fronius-emulator/lib/modbus-parser.js +61 -0
- package/fronius-emulator/lib/modbus-tcp-server.js +224 -0
- package/fronius-emulator/lib/validation.js +206 -0
- package/fronius-emulator/lib/virtual-meter.js +132 -0
- package/fronius-read/fronius-read.html +3944 -0
- package/fronius-read/fronius-read.js +1466 -0
- package/fronius-read/lib/inverter-profiles.js +711 -0
- package/fronius-read/lib/sunspec-core.js +303 -0
- package/fronius-read/lib/sunspec-model-parsers.js +845 -0
- package/fronius-write/fronius-write.html +1789 -0
- package/fronius-write/fronius-write.js +2531 -0
- package/influxdb/influxdb.html +1077 -0
- package/influxdb/influxdb.js +1487 -0
- package/janitza/janitza.html +2562 -0
- package/janitza/janitza.js +1500 -0
- package/janitza/lib/janitza-profiles.js +371 -0
- package/lib/a3-test-server.js +199 -0
- package/lib/adam-6000-profiles.js +173 -0
- package/lib/licensing/constants.js +103 -0
- package/lib/licensing/device-id.js +251 -0
- package/lib/licensing/errors.js +21 -0
- package/lib/licensing/license-client.js +377 -0
- package/lib/licensing/license-state.js +50 -0
- package/lib/licensing/node-guard.js +150 -0
- package/lib/licensing/package-integrity.js +167 -0
- package/lib/licensing/package-integrity.json +513 -0
- package/lib/licensing/public-key.pem +3 -0
- package/lib/licensing/public-key.pem.example +2 -0
- package/lib/licensing/public-keys.js +18 -0
- package/lib/licensing/storage.js +63 -0
- package/lib/licensing/token-verifier.js +84 -0
- package/lib/numbers.js +26 -0
- package/license/atelier-license.html +88 -0
- package/license/atelier-license.js +170 -0
- package/modbus-tcp-discover/modbus-tcp-discover.html +190 -0
- package/modbus-tcp-discover/modbus-tcp-discover.js +706 -0
- package/multi-battery/multi-battery.html +649 -0
- package/multi-battery/multi-battery.js +668 -0
- package/multi-grid/multi-grid.html +745 -0
- package/multi-grid/multi-grid.js +1392 -0
- package/multi-inverter/lib/engine-core.js +237 -0
- package/multi-inverter/multi-inverter.html +2674 -0
- package/multi-inverter/multi-inverter.js +1393 -0
- package/package.json +109 -0
- package/phoenix-contact/lib/eem-ma370-advanced.js +175 -0
- package/phoenix-contact/lib/eem-ma370.js +138 -0
- package/phoenix-contact/lib/integrations.js +149 -0
- package/phoenix-contact/lib/phoenix-contact-profile.js +35030 -0
- package/phoenix-contact/phoenix-contact.html +840 -0
- package/phoenix-contact/phoenix-contact.js +679 -0
- package/pv-generator/pv-generator.html +284 -0
- package/pv-generator/pv-generator.js +387 -0
- package/pylontech-read/pylontech-read.html +763 -0
- package/pylontech-read/pylontech-read.js +518 -0
- package/pylontech-write/pylontech-write.html +405 -0
- package/pylontech-write/pylontech-write.js +546 -0
- package/scada-aggregator/lib/aggregate.js +72 -0
- package/scada-aggregator/lib/groups.js +39 -0
- package/scada-aggregator/scada-aggregator.html +108 -0
- package/scada-aggregator/scada-aggregator.js +117 -0
- package/scada-server/lib/aggregator-map.js +58 -0
- package/scada-server/lib/encoding.js +235 -0
- package/scada-server/lib/modbus-server.js +492 -0
- package/scada-server/lib/object-path.js +18 -0
- package/scada-server/lib/register-map.js +288 -0
- package/scada-server/scada-server.html +1419 -0
- package/scada-server/scada-server.js +704 -0
- package/scripts/check-syntax.js +66 -0
- package/scripts/package-integrity.js +46 -0
- package/scripts/package-release.js +116 -0
- package/scripts/run-tests.js +2178 -0
- package/scripts/tgz-integrity.js +74 -0
- package/sma-read/lib/sunspec-core.js +83 -0
- package/sma-read/lib/sunspec-model-parsers.js +853 -0
- package/sma-read/sma-read.html +659 -0
- package/sma-read/sma-read.js +458 -0
- package/sma-write/sma-write.html +105 -0
- package/sma-write/sma-write.js +270 -0
- package/victron-read/lib/mqtt-state.js +176 -0
- package/victron-read/victron-read.html +1074 -0
- package/victron-read/victron-read.js +1222 -0
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.advantech-read-editor {
|
|
3
|
+
--pr-border: #d7dde5;
|
|
4
|
+
--pr-muted: #667085;
|
|
5
|
+
--pr-surface: #f8fafc;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.advantech-read-editor .ar-section {
|
|
9
|
+
margin: 0 0 18px;
|
|
10
|
+
padding: 14px 16px 16px;
|
|
11
|
+
border: 1px solid var(--pr-border);
|
|
12
|
+
border-radius: 8px;
|
|
13
|
+
background: var(--pr-surface);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.advantech-read-editor .ar-title {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 8px;
|
|
20
|
+
margin: 0 0 4px;
|
|
21
|
+
font-size: 15px;
|
|
22
|
+
font-weight: 600;
|
|
23
|
+
color: #243447;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.advantech-read-editor .ar-note {
|
|
27
|
+
margin: 0 0 14px;
|
|
28
|
+
color: var(--pr-muted);
|
|
29
|
+
font-size: 12px;
|
|
30
|
+
line-height: 1.45;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.advantech-read-editor .ar-grid {
|
|
34
|
+
display: grid;
|
|
35
|
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
36
|
+
gap: 12px 16px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.advantech-read-editor .form-row {
|
|
40
|
+
margin-bottom: 12px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.advantech-read-editor .ar-grid .form-row,
|
|
44
|
+
.advantech-read-editor .form-row:last-child {
|
|
45
|
+
margin-bottom: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.advantech-read-editor .form-row > label {
|
|
49
|
+
display: block;
|
|
50
|
+
width: auto;
|
|
51
|
+
margin: 0 0 6px;
|
|
52
|
+
font-weight: 600;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.advantech-read-editor .form-row > input[type="text"],
|
|
56
|
+
.advantech-read-editor .form-row > textarea,
|
|
57
|
+
.advantech-read-editor .form-row > select {
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
width: 100%;
|
|
60
|
+
max-width: 100%;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.advantech-read-editor .form-row > textarea {
|
|
64
|
+
min-height: 96px;
|
|
65
|
+
resize: vertical;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.advantech-read-editor .ar-checkbox {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: 10px;
|
|
72
|
+
min-height: 34px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.advantech-read-editor .ar-checkbox > label {
|
|
76
|
+
flex: 1;
|
|
77
|
+
margin: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.advantech-read-editor .ar-checkbox input {
|
|
81
|
+
display: inline-block;
|
|
82
|
+
width: auto;
|
|
83
|
+
margin: 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.advantech-read-editor .ar-inline-note {
|
|
87
|
+
display: block;
|
|
88
|
+
margin: 6px 0 0;
|
|
89
|
+
color: var(--pr-muted);
|
|
90
|
+
font-size: 12px;
|
|
91
|
+
line-height: 1.4;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.advantech-read-editor .ar-wide {
|
|
95
|
+
grid-column: 1 / -1;
|
|
96
|
+
max-width: 520px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.advantech-read-editor .ar-channel-grid {
|
|
100
|
+
display: grid;
|
|
101
|
+
grid-template-columns: repeat(2, minmax(280px, 1fr));
|
|
102
|
+
gap: 16px;
|
|
103
|
+
align-items: start;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.advantech-read-editor .ar-channel-column {
|
|
107
|
+
display: grid;
|
|
108
|
+
gap: 12px;
|
|
109
|
+
min-width: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.advantech-read-editor .ar-channel-title {
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding: 0 0 8px;
|
|
115
|
+
border-bottom: 1px solid var(--pr-border);
|
|
116
|
+
color: #243447;
|
|
117
|
+
font-size: 13px;
|
|
118
|
+
font-weight: 700;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.advantech-read-editor .ar-channel-column .form-row {
|
|
122
|
+
margin-bottom: 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.advantech-read-editor .ar-channel-column textarea {
|
|
126
|
+
min-height: 72px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.advantech-read-editor .ar-family-grid {
|
|
130
|
+
display: grid;
|
|
131
|
+
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
|
132
|
+
gap: 12px 16px;
|
|
133
|
+
margin-top: 16px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.advantech-read-editor .ar-advanced {
|
|
137
|
+
display: none;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (max-width: 720px) {
|
|
141
|
+
.advantech-read-editor .ar-channel-grid,
|
|
142
|
+
.advantech-read-editor .ar-family-grid {
|
|
143
|
+
grid-template-columns: 1fr;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
</style>
|
|
147
|
+
|
|
148
|
+
<script type="text/javascript">
|
|
149
|
+
const ADAM_CHANNEL_COUNTS = {
|
|
150
|
+
"6015": { di: 0, do: 0, ai: 7, ao: 0 },
|
|
151
|
+
"6017": { di: 0, do: 2, ai: 8, ao: 0 },
|
|
152
|
+
"6018": { di: 0, do: 8, ai: 8, ao: 0 },
|
|
153
|
+
"6018+": { di: 0, do: 0, ai: 8, ao: 0 },
|
|
154
|
+
"6022": { di: 2, do: 2, ai: 6, ao: 2 },
|
|
155
|
+
"6024": { di: 2, do: 2, ai: 6, ao: 2 },
|
|
156
|
+
"6050": { di: 12, do: 6, ai: 0, ao: 0 },
|
|
157
|
+
"6051": { di: 12, do: 2, ai: 0, ao: 0 },
|
|
158
|
+
"6052": { di: 8, do: 8, ai: 0, ao: 0 },
|
|
159
|
+
"6060": { di: 6, do: 6, ai: 0, ao: 0 },
|
|
160
|
+
"6066": { di: 6, do: 6, ai: 0, ao: 0 }
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
function normalizeAdamModel(value) {
|
|
164
|
+
const match = String(value || "").toUpperCase().match(/60\d{2}\+?/);
|
|
165
|
+
return match ? match[0] : "";
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function normalizeDiOutputCount(value) {
|
|
169
|
+
const count = Math.round(Number(value));
|
|
170
|
+
if (!Number.isFinite(count) || count < 1) return 1;
|
|
171
|
+
return Math.min(32, count);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function isPollOff(value) {
|
|
175
|
+
const text = String(value || "").trim().toLowerCase();
|
|
176
|
+
return text === "off" || text === "0";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function validPollValue(value) {
|
|
180
|
+
const text = String(value || "").trim().toLowerCase();
|
|
181
|
+
if (text === "off") return true;
|
|
182
|
+
const n = Number(text);
|
|
183
|
+
return Number.isFinite(n) && n >= 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function selectedProfileCounts() {
|
|
187
|
+
const model = normalizeAdamModel($("#node-input-moduleType").val());
|
|
188
|
+
return ADAM_CHANNEL_COUNTS[model] || {
|
|
189
|
+
di: normalizeDiOutputCount($("#node-input-diCount").val()),
|
|
190
|
+
do: normalizeDiOutputCount($("#node-input-doCount").val()),
|
|
191
|
+
ai: 0,
|
|
192
|
+
ao: 0
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function selectedDiCount() {
|
|
197
|
+
return selectedProfileCounts().di || normalizeDiOutputCount($("#node-input-diCount").val());
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function selectedDoCount() {
|
|
201
|
+
return selectedProfileCounts().do || normalizeDiOutputCount($("#node-input-doCount").val());
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function selectedAiCount() {
|
|
205
|
+
return selectedProfileCounts().ai || normalizeDiOutputCount($("#node-input-aiCount").val());
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function selectedAoCount() {
|
|
209
|
+
return selectedProfileCounts().ao || normalizeDiOutputCount($("#node-input-aoCount").val());
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function selectedSplitOutputCount() {
|
|
213
|
+
const counts = selectedProfileCounts();
|
|
214
|
+
let count = 0;
|
|
215
|
+
[
|
|
216
|
+
{ kind: "di", total: selectedDiCount(), read: "#node-input-readDi", mode: "#node-input-diOutputMode", available: counts.di > 0 },
|
|
217
|
+
{ kind: "do", total: selectedDoCount(), read: "#node-input-readDo", mode: "#node-input-doOutputMode", available: counts.do > 0 },
|
|
218
|
+
{ kind: "ai", total: selectedAiCount(), read: "#node-input-readAi", mode: "#node-input-aiOutputMode", available: counts.ai > 0 },
|
|
219
|
+
{ kind: "ao", total: selectedAoCount(), read: "#node-input-readAo", mode: "#node-input-aoOutputMode", available: counts.ao > 0 }
|
|
220
|
+
].forEach(function (family) {
|
|
221
|
+
if (!family.available || !$(family.read).is(":checked")) return;
|
|
222
|
+
count += $(family.mode).val() === "split" ? family.total : 1;
|
|
223
|
+
});
|
|
224
|
+
if ($("#node-input-debugOutput").is(":checked")) count += 1;
|
|
225
|
+
return count > 0 ? count : 1;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function safeDiGlobalPart(value, fallback) {
|
|
229
|
+
const text = String(value || fallback || "adam")
|
|
230
|
+
.trim()
|
|
231
|
+
.toLowerCase()
|
|
232
|
+
.replace(/^adam-/, "adam_")
|
|
233
|
+
.replace(/[^a-z0-9_]+/g, "_")
|
|
234
|
+
.replace(/^_+|_+$/g, "");
|
|
235
|
+
return text || String(fallback || "adam");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function selectedChannelCount(kind) {
|
|
239
|
+
if (kind === "do") return selectedDoCount();
|
|
240
|
+
if (kind === "ai") return selectedAiCount();
|
|
241
|
+
if (kind === "ao") return selectedAoCount();
|
|
242
|
+
return selectedDiCount();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function buildChannelGlobalNamesPreview(kind) {
|
|
246
|
+
const rawPrefix = $("#node-input-" + kind + "GlobalPrefix").val();
|
|
247
|
+
const base = safeDiGlobalPart(rawPrefix || "advantech", "advantech");
|
|
248
|
+
const count = selectedChannelCount(kind);
|
|
249
|
+
const names = [];
|
|
250
|
+
for (let i = 0; i < count; i += 1) {
|
|
251
|
+
names.push(base + "_" + kind + (i + 1));
|
|
252
|
+
}
|
|
253
|
+
return names.join("\n");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
RED.nodes.registerType("advantech-read", {
|
|
257
|
+
category: "Atelierul de Tehnologii",
|
|
258
|
+
color: "#F59E0B",
|
|
259
|
+
defaults: {
|
|
260
|
+
license: { value: "", type: "atelier-license", required: true },
|
|
261
|
+
name: { value: "" },
|
|
262
|
+
host: { value: "", required: true },
|
|
263
|
+
port: { value: 502, required: true, validate: RED.validators.number() },
|
|
264
|
+
unitId: { value: 1, required: true, validate: RED.validators.number() },
|
|
265
|
+
pollInterval: { value: 5000, validate: validPollValue },
|
|
266
|
+
addressMode: { value: "manual" },
|
|
267
|
+
moduleType: { value: "ADAM-6066" },
|
|
268
|
+
diOutputMode: { value: "aggregate" },
|
|
269
|
+
doOutputMode: { value: "aggregate" },
|
|
270
|
+
aiOutputMode: { value: "aggregate" },
|
|
271
|
+
aoOutputMode: { value: "aggregate" },
|
|
272
|
+
saveDiGlobals: { value: false },
|
|
273
|
+
saveDoGlobals: { value: false },
|
|
274
|
+
saveAiGlobals: { value: false },
|
|
275
|
+
saveAoGlobals: { value: false },
|
|
276
|
+
debugOutput: { value: false },
|
|
277
|
+
diGlobalPrefix: { value: "" },
|
|
278
|
+
doGlobalPrefix: { value: "" },
|
|
279
|
+
aiGlobalPrefix: { value: "" },
|
|
280
|
+
aoGlobalPrefix: { value: "" },
|
|
281
|
+
diGlobalNames: { value: "" },
|
|
282
|
+
doGlobalNames: { value: "" },
|
|
283
|
+
aiGlobalNames: { value: "" },
|
|
284
|
+
aoGlobalNames: { value: "" },
|
|
285
|
+
readDi: { value: true },
|
|
286
|
+
readDo: { value: true },
|
|
287
|
+
readAi: { value: true },
|
|
288
|
+
readAo: { value: true },
|
|
289
|
+
diStart: { value: 1, validate: RED.validators.number() },
|
|
290
|
+
doStart: { value: 17, validate: RED.validators.number() },
|
|
291
|
+
aiStart: { value: 40001, validate: RED.validators.number() },
|
|
292
|
+
aoStart: { value: 40011, validate: RED.validators.number() },
|
|
293
|
+
diCount: { value: 12, validate: RED.validators.number() },
|
|
294
|
+
doCount: { value: 6, validate: RED.validators.number() },
|
|
295
|
+
aiCount: { value: 0, validate: RED.validators.number() },
|
|
296
|
+
aoCount: { value: 0, validate: RED.validators.number() },
|
|
297
|
+
aiFormat: { value: "int16" },
|
|
298
|
+
aiScale: { value: 1, validate: RED.validators.number() },
|
|
299
|
+
aiOffset: { value: 0, validate: RED.validators.number() },
|
|
300
|
+
aoScale: { value: 1, validate: RED.validators.number() },
|
|
301
|
+
aoOffset: { value: 0, validate: RED.validators.number() },
|
|
302
|
+
wordOrder: { value: "msw_first" },
|
|
303
|
+
outputs: { value: 1 },
|
|
304
|
+
inputs: { value: 0 }
|
|
305
|
+
},
|
|
306
|
+
inputs: 0,
|
|
307
|
+
outputs: 1,
|
|
308
|
+
icon: "font-awesome/fa-microchip",
|
|
309
|
+
label: function () {
|
|
310
|
+
return this.name || this.host || "advantech-read";
|
|
311
|
+
},
|
|
312
|
+
outputLabels: function (index) {
|
|
313
|
+
const counts = ADAM_CHANNEL_COUNTS[normalizeAdamModel(this.moduleType)] || { di: 0, do: 0, ai: 0, ao: 0 };
|
|
314
|
+
const families = [
|
|
315
|
+
{ kind: "di", label: "DI", enabled: this.readDi !== false, mode: this.diOutputMode, count: counts.di || 0 },
|
|
316
|
+
{ kind: "do", label: "DO", enabled: this.readDo !== false, mode: this.doOutputMode, count: counts.do || 0 },
|
|
317
|
+
{ kind: "ai", label: "AI", enabled: this.readAi !== false, mode: this.aiOutputMode, count: counts.ai || 0 },
|
|
318
|
+
{ kind: "ao", label: "AO", enabled: this.readAo !== false, mode: this.aoOutputMode, count: counts.ao || 0 }
|
|
319
|
+
];
|
|
320
|
+
for (let i = 0; i < families.length; i += 1) {
|
|
321
|
+
const family = families[i];
|
|
322
|
+
if (!family.enabled || family.count <= 0) continue;
|
|
323
|
+
if (family.mode === "split") {
|
|
324
|
+
if (index < family.count) return family.label + " " + (index + 1);
|
|
325
|
+
index -= family.count;
|
|
326
|
+
} else {
|
|
327
|
+
if (index === 0) return family.label;
|
|
328
|
+
index -= 1;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (this.debugOutput && index === 0) return "debug";
|
|
332
|
+
return "payload";
|
|
333
|
+
},
|
|
334
|
+
oneditprepare: function () {
|
|
335
|
+
const node = this;
|
|
336
|
+
let advancedUnlocked = false;
|
|
337
|
+
let longPressTimer = null;
|
|
338
|
+
let longPressTriggered = false;
|
|
339
|
+
|
|
340
|
+
function clearLongPressTimer() {
|
|
341
|
+
if (longPressTimer) {
|
|
342
|
+
clearTimeout(longPressTimer);
|
|
343
|
+
longPressTimer = null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function syncAdvancedRows() {
|
|
348
|
+
$(".advantech-read-editor .ar-advanced").toggle(advancedUnlocked);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function syncOutputs() {
|
|
352
|
+
node.outputs = selectedSplitOutputCount();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function syncInputs() {
|
|
356
|
+
node.inputs = isPollOff($("#node-input-pollInterval").val()) ? 1 : 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function syncGlobalRows() {
|
|
360
|
+
const diEnabled = $("#node-input-saveDiGlobals").is(":checked");
|
|
361
|
+
const doEnabled = $("#node-input-saveDoGlobals").is(":checked");
|
|
362
|
+
const aiEnabled = $("#node-input-saveAiGlobals").is(":checked");
|
|
363
|
+
const aoEnabled = $("#node-input-saveAoGlobals").is(":checked");
|
|
364
|
+
$("#row-di-global-prefix, #row-di-global-names").toggle(diEnabled);
|
|
365
|
+
$("#row-do-global-prefix, #row-do-global-names").toggle(doEnabled);
|
|
366
|
+
$("#row-ai-global-prefix, #row-ai-global-names").toggle(aiEnabled);
|
|
367
|
+
$("#row-ao-global-prefix, #row-ao-global-names").toggle(aoEnabled);
|
|
368
|
+
$("#node-input-diGlobalNames").attr("placeholder", buildChannelGlobalNamesPreview("di"));
|
|
369
|
+
$("#node-input-doGlobalNames").attr("placeholder", buildChannelGlobalNamesPreview("do"));
|
|
370
|
+
$("#node-input-aiGlobalNames").attr("placeholder", buildChannelGlobalNamesPreview("ai"));
|
|
371
|
+
$("#node-input-aoGlobalNames").attr("placeholder", buildChannelGlobalNamesPreview("ao"));
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function syncChannelRows() {
|
|
375
|
+
const counts = selectedProfileCounts();
|
|
376
|
+
const hasDi = counts.di > 0;
|
|
377
|
+
const hasDo = counts.do > 0;
|
|
378
|
+
const hasAi = counts.ai > 0;
|
|
379
|
+
const hasAo = counts.ao > 0;
|
|
380
|
+
|
|
381
|
+
$(".row-di-family").css("display", hasDi ? "" : "none");
|
|
382
|
+
$(".row-do-family").css("display", hasDo ? "" : "none");
|
|
383
|
+
$(".row-ai-family").css("display", hasAi ? "" : "none");
|
|
384
|
+
$(".row-ao-family").css("display", hasAo ? "" : "none");
|
|
385
|
+
$(".row-read-di, .row-di-output, .row-di-globals").toggle(hasDi);
|
|
386
|
+
$(".row-read-do, .row-do-output, .row-do-globals").toggle(hasDo);
|
|
387
|
+
$(".row-read-ai, .row-ai-output, .row-ai-globals").toggle(hasAi);
|
|
388
|
+
$(".row-read-ao, .row-ao-output, .row-ao-globals").toggle(hasAo);
|
|
389
|
+
|
|
390
|
+
if (!hasDi) {
|
|
391
|
+
$("#node-input-readDi").prop("checked", false);
|
|
392
|
+
$("#node-input-diOutputMode").val("aggregate");
|
|
393
|
+
$("#node-input-saveDiGlobals").prop("checked", false);
|
|
394
|
+
}
|
|
395
|
+
if (!hasDo) {
|
|
396
|
+
$("#node-input-readDo").prop("checked", false);
|
|
397
|
+
$("#node-input-doOutputMode").val("aggregate");
|
|
398
|
+
$("#node-input-saveDoGlobals").prop("checked", false);
|
|
399
|
+
}
|
|
400
|
+
if (!hasAi) {
|
|
401
|
+
$("#node-input-readAi").prop("checked", false);
|
|
402
|
+
$("#node-input-aiOutputMode").val("aggregate");
|
|
403
|
+
$("#node-input-saveAiGlobals").prop("checked", false);
|
|
404
|
+
}
|
|
405
|
+
if (!hasAo) {
|
|
406
|
+
$("#node-input-readAo").prop("checked", false);
|
|
407
|
+
$("#node-input-aoOutputMode").val("aggregate");
|
|
408
|
+
$("#node-input-saveAoGlobals").prop("checked", false);
|
|
409
|
+
}
|
|
410
|
+
syncOutputs();
|
|
411
|
+
syncGlobalRows();
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function startLongPress() {
|
|
415
|
+
longPressTriggered = false;
|
|
416
|
+
clearLongPressTimer();
|
|
417
|
+
longPressTimer = setTimeout(function () {
|
|
418
|
+
advancedUnlocked = true;
|
|
419
|
+
longPressTriggered = true;
|
|
420
|
+
syncAdvancedRows();
|
|
421
|
+
}, 5000);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function setupLongPress() {
|
|
425
|
+
$("#node-input-readDi")
|
|
426
|
+
.off(".advantechReadExpert")
|
|
427
|
+
.on("mousedown.advantechReadExpert touchstart.advantechReadExpert", function () {
|
|
428
|
+
startLongPress();
|
|
429
|
+
})
|
|
430
|
+
.on("mouseup.advantechReadExpert mouseleave.advantechReadExpert touchend.advantechReadExpert touchcancel.advantechReadExpert", function () {
|
|
431
|
+
clearLongPressTimer();
|
|
432
|
+
})
|
|
433
|
+
.on("click.advantechReadExpert", function (evt) {
|
|
434
|
+
if (!longPressTriggered) return;
|
|
435
|
+
evt.preventDefault();
|
|
436
|
+
evt.stopImmediatePropagation();
|
|
437
|
+
$(this).prop("checked", true).trigger("change");
|
|
438
|
+
longPressTriggered = false;
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
$("#node-input-moduleType, #node-input-diOutputMode, #node-input-doOutputMode, #node-input-aiOutputMode, #node-input-aoOutputMode, #node-input-diCount, #node-input-doCount, #node-input-aiCount, #node-input-aoCount, #node-input-readDi, #node-input-readDo, #node-input-readAi, #node-input-readAo")
|
|
443
|
+
.on("change.advantechRead input.advantechRead", function () {
|
|
444
|
+
syncChannelRows();
|
|
445
|
+
});
|
|
446
|
+
$("#node-input-pollInterval")
|
|
447
|
+
.on("change.advantechRead input.advantechRead", syncInputs);
|
|
448
|
+
$("#node-input-debugOutput")
|
|
449
|
+
.on("change.advantechRead input.advantechRead", syncOutputs);
|
|
450
|
+
$("#node-input-saveDiGlobals, #node-input-saveDoGlobals, #node-input-saveAiGlobals, #node-input-saveAoGlobals, #node-input-name, #node-input-host, #node-input-diGlobalPrefix, #node-input-doGlobalPrefix, #node-input-aiGlobalPrefix, #node-input-aoGlobalPrefix")
|
|
451
|
+
.on("change.advantechRead input.advantechRead", syncGlobalRows);
|
|
452
|
+
$("#node-input-host")
|
|
453
|
+
.off(".advantechReadName")
|
|
454
|
+
.on("change.advantechReadName input.advantechReadName", function () {
|
|
455
|
+
$("#node-input-name").val(String($(this).val() || "").trim());
|
|
456
|
+
});
|
|
457
|
+
$("#row-manual-counts").hide();
|
|
458
|
+
$("#module-type-note").text("Profilul ales stabileste automat numarul de DI, DO, AI si AO.");
|
|
459
|
+
syncAdvancedRows();
|
|
460
|
+
syncChannelRows();
|
|
461
|
+
syncInputs();
|
|
462
|
+
setupLongPress();
|
|
463
|
+
},
|
|
464
|
+
oneditsave: function () {
|
|
465
|
+
const diSplit = $("#node-input-diOutputMode").val() === "split";
|
|
466
|
+
const doSplit = $("#node-input-doOutputMode").val() === "split";
|
|
467
|
+
const aiSplit = $("#node-input-aiOutputMode").val() === "split";
|
|
468
|
+
const aoSplit = $("#node-input-aoOutputMode").val() === "split";
|
|
469
|
+
this.diOutputMode = diSplit ? "split" : "aggregate";
|
|
470
|
+
this.doOutputMode = doSplit ? "split" : "aggregate";
|
|
471
|
+
this.aiOutputMode = aiSplit ? "split" : "aggregate";
|
|
472
|
+
this.aoOutputMode = aoSplit ? "split" : "aggregate";
|
|
473
|
+
this.outputs = selectedSplitOutputCount();
|
|
474
|
+
this.inputs = isPollOff($("#node-input-pollInterval").val()) ? 1 : 0;
|
|
475
|
+
$("#node-input-moduleType, #node-input-diOutputMode, #node-input-doOutputMode, #node-input-aiOutputMode, #node-input-aoOutputMode, #node-input-diCount, #node-input-doCount, #node-input-aiCount, #node-input-aoCount, #node-input-readDi, #node-input-readDo, #node-input-readAi, #node-input-readAo, #node-input-pollInterval, #node-input-debugOutput, #node-input-saveDiGlobals, #node-input-saveDoGlobals, #node-input-saveAiGlobals, #node-input-saveAoGlobals, #node-input-name, #node-input-host, #node-input-diGlobalPrefix, #node-input-doGlobalPrefix, #node-input-aiGlobalPrefix, #node-input-aoGlobalPrefix").off(".advantechRead");
|
|
476
|
+
$("#node-input-host").off(".advantechReadName");
|
|
477
|
+
$("#node-input-readDi").off(".advantechReadExpert");
|
|
478
|
+
},
|
|
479
|
+
oneditcancel: function () {
|
|
480
|
+
$("#node-input-moduleType, #node-input-diOutputMode, #node-input-doOutputMode, #node-input-aiOutputMode, #node-input-aoOutputMode, #node-input-diCount, #node-input-doCount, #node-input-aiCount, #node-input-aoCount, #node-input-readDi, #node-input-readDo, #node-input-readAi, #node-input-readAo, #node-input-pollInterval, #node-input-debugOutput, #node-input-saveDiGlobals, #node-input-saveDoGlobals, #node-input-saveAiGlobals, #node-input-saveAoGlobals, #node-input-name, #node-input-host, #node-input-diGlobalPrefix, #node-input-doGlobalPrefix, #node-input-aiGlobalPrefix, #node-input-aoGlobalPrefix").off(".advantechRead");
|
|
481
|
+
$("#node-input-host").off(".advantechReadName");
|
|
482
|
+
$("#node-input-readDi").off(".advantechReadExpert");
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
</script>
|
|
486
|
+
|
|
487
|
+
<script type="text/html" data-template-name="advantech-read">
|
|
488
|
+
<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>
|
|
489
|
+
<div class="advantech-read-editor">
|
|
490
|
+
<div class="ar-section">
|
|
491
|
+
<p class="ar-title"><i class="fa fa-microchip"></i> Advantech ADAM Reader</p>
|
|
492
|
+
<p class="ar-note">Citire Modbus TCP pentru module ADAM-6000, pe baza profilului de modul ales.</p>
|
|
493
|
+
<div class="ar-grid">
|
|
494
|
+
<div class="form-row">
|
|
495
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
496
|
+
<input type="text" id="node-input-name" placeholder="advantech-read">
|
|
497
|
+
</div>
|
|
498
|
+
<div class="form-row">
|
|
499
|
+
<label for="node-input-host"><i class="fa fa-plug"></i> Host</label>
|
|
500
|
+
<input type="text" id="node-input-host" placeholder="192.168.1.50">
|
|
501
|
+
</div>
|
|
502
|
+
<div class="form-row">
|
|
503
|
+
<label for="node-input-port"><i class="fa fa-ellipsis-h"></i> Port</label>
|
|
504
|
+
<input type="text" id="node-input-port" placeholder="502">
|
|
505
|
+
</div>
|
|
506
|
+
<div class="form-row">
|
|
507
|
+
<label for="node-input-unitId"><i class="fa fa-hashtag"></i> Unit ID</label>
|
|
508
|
+
<input type="text" id="node-input-unitId" placeholder="1">
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
</div>
|
|
512
|
+
|
|
513
|
+
<div class="ar-section">
|
|
514
|
+
<p class="ar-title"><i class="fa fa-cube"></i> Module Profile</p>
|
|
515
|
+
<p class="ar-note">Alege modelul ADAM instalat. Profilul ales este folosit direct pentru numarul de canale, fara detectie automata din registrul modulului.</p>
|
|
516
|
+
<div class="ar-grid">
|
|
517
|
+
<div class="form-row" id="row-module-type">
|
|
518
|
+
<label for="node-input-moduleType"><i class="fa fa-cube"></i> Module</label>
|
|
519
|
+
<select id="node-input-moduleType">
|
|
520
|
+
<option value="ADAM-6015">ADAM-6015</option>
|
|
521
|
+
<option value="ADAM-6017">ADAM-6017</option>
|
|
522
|
+
<option value="ADAM-6018">ADAM-6018</option>
|
|
523
|
+
<option value="ADAM-6018+">ADAM-6018+</option>
|
|
524
|
+
<option value="ADAM-6022">ADAM-6022</option>
|
|
525
|
+
<option value="ADAM-6024">ADAM-6024</option>
|
|
526
|
+
<option value="ADAM-6050">ADAM-6050</option>
|
|
527
|
+
<option value="ADAM-6051">ADAM-6051</option>
|
|
528
|
+
<option value="ADAM-6052">ADAM-6052</option>
|
|
529
|
+
<option value="ADAM-6060">ADAM-6060</option>
|
|
530
|
+
<option value="ADAM-6066">ADAM-6066</option>
|
|
531
|
+
</select>
|
|
532
|
+
<span class="ar-inline-note" id="module-type-note"></span>
|
|
533
|
+
</div>
|
|
534
|
+
<div class="form-row">
|
|
535
|
+
<label for="node-input-pollInterval"><i class="fa fa-clock-o"></i> Poll</label>
|
|
536
|
+
<input type="text" id="node-input-pollInterval" placeholder="5000 sau off">
|
|
537
|
+
</div>
|
|
538
|
+
<div class="form-row ar-checkbox">
|
|
539
|
+
<label for="node-input-debugOutput"><i class="fa fa-bug"></i> Debug output</label>
|
|
540
|
+
<input type="checkbox" id="node-input-debugOutput">
|
|
541
|
+
</div>
|
|
542
|
+
<div class="form-row ar-advanced">
|
|
543
|
+
<label for="node-input-addressMode"><i class="fa fa-map-marker"></i> Addresses</label>
|
|
544
|
+
<select id="node-input-addressMode">
|
|
545
|
+
<option value="manual">Manual format (00017 / 40011)</option>
|
|
546
|
+
<option value="zero">Zero-based Modbus offsets</option>
|
|
547
|
+
</select>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
</div>
|
|
551
|
+
|
|
552
|
+
<div class="ar-section">
|
|
553
|
+
<p class="ar-title"><i class="fa fa-random"></i> Channels</p>
|
|
554
|
+
<p class="ar-note">Numarul de canale este calculat din profilul ales. Bifele controleaza ce familii se includ in payload.</p>
|
|
555
|
+
<div class="ar-channel-grid">
|
|
556
|
+
<div class="ar-channel-column row-di-family">
|
|
557
|
+
<p class="ar-channel-title">Digital Inputs</p>
|
|
558
|
+
<div class="form-row ar-checkbox row-read-di"><label for="node-input-readDi">Read DI</label><input type="checkbox" id="node-input-readDi"></div>
|
|
559
|
+
<div class="form-row row-di-output">
|
|
560
|
+
<label for="node-input-diOutputMode">DI Output</label>
|
|
561
|
+
<select id="node-input-diOutputMode">
|
|
562
|
+
<option value="aggregate">All data on one output</option>
|
|
563
|
+
<option value="split">Separate DI outputs</option>
|
|
564
|
+
</select>
|
|
565
|
+
</div>
|
|
566
|
+
<div class="form-row ar-checkbox row-di-globals">
|
|
567
|
+
<label for="node-input-saveDiGlobals">Save DI globals</label>
|
|
568
|
+
<input type="checkbox" id="node-input-saveDiGlobals">
|
|
569
|
+
</div>
|
|
570
|
+
<div class="form-row row-di-globals" id="row-di-global-prefix">
|
|
571
|
+
<label for="node-input-diGlobalPrefix">DI global prefix</label>
|
|
572
|
+
<input type="text" id="node-input-diGlobalPrefix" placeholder="advantech">
|
|
573
|
+
</div>
|
|
574
|
+
<div class="form-row row-di-globals" id="row-di-global-names">
|
|
575
|
+
<label for="node-input-diGlobalNames">DI global names</label>
|
|
576
|
+
<textarea id="node-input-diGlobalNames" placeholder="cate un nume pe linie"></textarea>
|
|
577
|
+
<span class="ar-inline-note">Gol = se folosesc numele generate automat.</span>
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
|
|
581
|
+
<div class="ar-channel-column row-do-family">
|
|
582
|
+
<p class="ar-channel-title">Digital Outputs</p>
|
|
583
|
+
<div class="form-row ar-checkbox row-read-do"><label for="node-input-readDo">Read DO</label><input type="checkbox" id="node-input-readDo"></div>
|
|
584
|
+
<div class="form-row row-do-output">
|
|
585
|
+
<label for="node-input-doOutputMode">DO Output</label>
|
|
586
|
+
<select id="node-input-doOutputMode">
|
|
587
|
+
<option value="aggregate">All data on one output</option>
|
|
588
|
+
<option value="split">Separate DO outputs</option>
|
|
589
|
+
</select>
|
|
590
|
+
</div>
|
|
591
|
+
<div class="form-row ar-checkbox row-do-globals">
|
|
592
|
+
<label for="node-input-saveDoGlobals">Save DO globals</label>
|
|
593
|
+
<input type="checkbox" id="node-input-saveDoGlobals">
|
|
594
|
+
</div>
|
|
595
|
+
<div class="form-row row-do-globals" id="row-do-global-prefix">
|
|
596
|
+
<label for="node-input-doGlobalPrefix">DO global prefix</label>
|
|
597
|
+
<input type="text" id="node-input-doGlobalPrefix" placeholder="advantech">
|
|
598
|
+
</div>
|
|
599
|
+
<div class="form-row row-do-globals" id="row-do-global-names">
|
|
600
|
+
<label for="node-input-doGlobalNames">DO global names</label>
|
|
601
|
+
<textarea id="node-input-doGlobalNames" placeholder="cate un nume pe linie"></textarea>
|
|
602
|
+
<span class="ar-inline-note">Gol = se folosesc numele generate automat.</span>
|
|
603
|
+
</div>
|
|
604
|
+
</div>
|
|
605
|
+
|
|
606
|
+
<div class="ar-channel-column row-ai-family">
|
|
607
|
+
<p class="ar-channel-title">Analog Inputs</p>
|
|
608
|
+
<div class="form-row ar-checkbox row-read-ai"><label for="node-input-readAi">Read AI</label><input type="checkbox" id="node-input-readAi"></div>
|
|
609
|
+
<div class="form-row row-ai-output">
|
|
610
|
+
<label for="node-input-aiOutputMode">AI Output</label>
|
|
611
|
+
<select id="node-input-aiOutputMode">
|
|
612
|
+
<option value="aggregate">All data on one output</option>
|
|
613
|
+
<option value="split">Separate AI outputs</option>
|
|
614
|
+
</select>
|
|
615
|
+
</div>
|
|
616
|
+
<div class="form-row ar-checkbox row-ai-globals">
|
|
617
|
+
<label for="node-input-saveAiGlobals">Save AI globals</label>
|
|
618
|
+
<input type="checkbox" id="node-input-saveAiGlobals">
|
|
619
|
+
</div>
|
|
620
|
+
<div class="form-row row-ai-globals" id="row-ai-global-prefix">
|
|
621
|
+
<label for="node-input-aiGlobalPrefix">AI global prefix</label>
|
|
622
|
+
<input type="text" id="node-input-aiGlobalPrefix" placeholder="advantech">
|
|
623
|
+
</div>
|
|
624
|
+
<div class="form-row row-ai-globals" id="row-ai-global-names">
|
|
625
|
+
<label for="node-input-aiGlobalNames">AI global names</label>
|
|
626
|
+
<textarea id="node-input-aiGlobalNames" placeholder="cate un nume pe linie"></textarea>
|
|
627
|
+
<span class="ar-inline-note">Gol = se folosesc numele generate automat.</span>
|
|
628
|
+
</div>
|
|
629
|
+
</div>
|
|
630
|
+
|
|
631
|
+
<div class="ar-channel-column row-ao-family">
|
|
632
|
+
<p class="ar-channel-title">Analog Outputs</p>
|
|
633
|
+
<div class="form-row ar-checkbox row-read-ao"><label for="node-input-readAo">Read AO</label><input type="checkbox" id="node-input-readAo"></div>
|
|
634
|
+
<div class="form-row row-ao-output">
|
|
635
|
+
<label for="node-input-aoOutputMode">AO Output</label>
|
|
636
|
+
<select id="node-input-aoOutputMode">
|
|
637
|
+
<option value="aggregate">All data on one output</option>
|
|
638
|
+
<option value="split">Separate AO outputs</option>
|
|
639
|
+
</select>
|
|
640
|
+
</div>
|
|
641
|
+
<div class="form-row ar-checkbox row-ao-globals">
|
|
642
|
+
<label for="node-input-saveAoGlobals">Save AO globals</label>
|
|
643
|
+
<input type="checkbox" id="node-input-saveAoGlobals">
|
|
644
|
+
</div>
|
|
645
|
+
<div class="form-row row-ao-globals" id="row-ao-global-prefix">
|
|
646
|
+
<label for="node-input-aoGlobalPrefix">AO global prefix</label>
|
|
647
|
+
<input type="text" id="node-input-aoGlobalPrefix" placeholder="advantech">
|
|
648
|
+
</div>
|
|
649
|
+
<div class="form-row row-ao-globals" id="row-ao-global-names">
|
|
650
|
+
<label for="node-input-aoGlobalNames">AO global names</label>
|
|
651
|
+
<textarea id="node-input-aoGlobalNames" placeholder="cate un nume pe linie"></textarea>
|
|
652
|
+
<span class="ar-inline-note">Gol = se folosesc numele generate automat.</span>
|
|
653
|
+
</div>
|
|
654
|
+
</div>
|
|
655
|
+
</div>
|
|
656
|
+
|
|
657
|
+
<div class="ar-family-grid">
|
|
658
|
+
<div class="form-row ar-advanced"><label for="node-input-diStart">DI Start</label><input type="text" id="node-input-diStart" placeholder="1"></div>
|
|
659
|
+
<div class="form-row ar-advanced"><label for="node-input-doStart">DO Start</label><input type="text" id="node-input-doStart" placeholder="17"></div>
|
|
660
|
+
<div class="form-row ar-advanced"><label for="node-input-aiStart">AI Start</label><input type="text" id="node-input-aiStart" placeholder="40001"></div>
|
|
661
|
+
<div class="form-row ar-advanced"><label for="node-input-aoStart">AO Start</label><input type="text" id="node-input-aoStart" placeholder="40011"></div>
|
|
662
|
+
</div>
|
|
663
|
+
<div class="ar-grid ar-advanced" id="row-manual-counts" style="margin-top:12px;">
|
|
664
|
+
<div class="form-row"><label for="node-input-diCount">DI Count</label><input type="text" id="node-input-diCount" placeholder="12"></div>
|
|
665
|
+
<div class="form-row"><label for="node-input-doCount">DO Count</label><input type="text" id="node-input-doCount" placeholder="6"></div>
|
|
666
|
+
<div class="form-row"><label for="node-input-aiCount">AI Count</label><input type="text" id="node-input-aiCount" placeholder="0"></div>
|
|
667
|
+
<div class="form-row"><label for="node-input-aoCount">AO Count</label><input type="text" id="node-input-aoCount" placeholder="0"></div>
|
|
668
|
+
</div>
|
|
669
|
+
</div>
|
|
670
|
+
|
|
671
|
+
<div class="ar-section ar-advanced">
|
|
672
|
+
<p class="ar-title"><i class="fa fa-sliders"></i> Analog Scaling</p>
|
|
673
|
+
<p class="ar-note">AI poate fi citit ca int16 scalat sau ca perechi IEEE754, conform mapping-ului disponibil pe modul.</p>
|
|
674
|
+
<div class="ar-grid">
|
|
675
|
+
<div class="form-row">
|
|
676
|
+
<label for="node-input-aiFormat">AI Format</label>
|
|
677
|
+
<select id="node-input-aiFormat">
|
|
678
|
+
<option value="int16">Signed int16 + scale</option>
|
|
679
|
+
<option value="float32">IEEE754 float32 pairs</option>
|
|
680
|
+
</select>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="form-row"><label for="node-input-aiScale">AI Scale</label><input type="text" id="node-input-aiScale" placeholder="1"></div>
|
|
683
|
+
<div class="form-row"><label for="node-input-aiOffset">AI Offset</label><input type="text" id="node-input-aiOffset" placeholder="0"></div>
|
|
684
|
+
<div class="form-row">
|
|
685
|
+
<label for="node-input-wordOrder">Float Words</label>
|
|
686
|
+
<select id="node-input-wordOrder">
|
|
687
|
+
<option value="msw_first">MSW first</option>
|
|
688
|
+
<option value="lsw_first">LSW first</option>
|
|
689
|
+
</select>
|
|
690
|
+
</div>
|
|
691
|
+
<div class="form-row"><label for="node-input-aoScale">AO Scale</label><input type="text" id="node-input-aoScale" placeholder="1"></div>
|
|
692
|
+
<div class="form-row"><label for="node-input-aoOffset">AO Offset</label><input type="text" id="node-input-aoOffset" placeholder="0"></div>
|
|
693
|
+
</div>
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
</script>
|
|
697
|
+
|
|
698
|
+
<script type="text/html" data-help-name="advantech-read">
|
|
699
|
+
<p>Nodul <b>advantech-read</b> citeste module Advantech ADAM-6000 prin Modbus TCP.</p>
|
|
700
|
+
|
|
701
|
+
<h3>Conectare</h3>
|
|
702
|
+
<ul>
|
|
703
|
+
<li><b>Host</b> - adresa IP a modulului ADAM.</li>
|
|
704
|
+
<li><b>Port</b> - portul Modbus TCP, implicit <code>502</code>.</li>
|
|
705
|
+
<li><b>Unit ID</b> - adresa slave Modbus, de obicei <code>1</code>.</li>
|
|
706
|
+
<li><b>Poll</b> - intervalul de citire automata in milisecunde. Valoarea <code>off</code> sau <code>0</code> opreste poll-ul intern si activeaza intrarea nodului pentru trigger manual.</li>
|
|
707
|
+
</ul>
|
|
708
|
+
|
|
709
|
+
<h3>Profil modul</h3>
|
|
710
|
+
<p>Alege modelul real al modulului in campul <b>Module</b>. Nodul foloseste direct profilul ales pentru numarul de DI, DO, AI si AO, fara sa mai citeasca registrul de identificare al modulului.</p>
|
|
711
|
+
<p>Aceasta abordare evita cazul in care un ADAM-6066 raporteaza prin registru codul ADAM-6060. Pentru ADAM-6066, alege explicit <b>ADAM-6066</b>.</p>
|
|
712
|
+
|
|
713
|
+
<h3>Canale digitale</h3>
|
|
714
|
+
<p>In sectiunea <b>Channels</b>, setarile sunt grupate pe familii: <b>Digital Inputs</b>, <b>Digital Outputs</b>, <b>Analog Inputs</b> si <b>Analog Outputs</b>. Fiecare familie contine bifa de citire, modul de iesire si salvarea in context global pentru familia respectiva.</p>
|
|
715
|
+
<p><b>DI Output</b> poate pastra payload-ul complet pe o singura iesire sau poate crea iesiri separate pentru fiecare DI. In modul separat, fiecare iesire trimite <code>msg.payload</code> boolean pentru canalul DI aferent.</p>
|
|
716
|
+
<p><b>DO Output</b> functioneaza identic pentru iesirile digitale citite: agregat in payload sau cate o iesire Node-RED pentru fiecare DO.</p>
|
|
717
|
+
<ul>
|
|
718
|
+
<li><b>All data on one output</b> - familia respectiva trimite un singur mesaj agregat pe propria iesire.</li>
|
|
719
|
+
<li><b>Separate DI outputs</b> - nodul creeaza automat cate o iesire pentru fiecare DI detectat sau configurat.</li>
|
|
720
|
+
<li><b>Separate DO outputs</b> - nodul creeaza automat cate o iesire pentru fiecare DO citit.</li>
|
|
721
|
+
<li><b>Separate AI outputs</b> - nodul creeaza automat cate o iesire pentru fiecare AI citit.</li>
|
|
722
|
+
<li><b>Separate AO outputs</b> - nodul creeaza automat cate o iesire pentru fiecare AO citit.</li>
|
|
723
|
+
</ul>
|
|
724
|
+
<p>Poti combina modurile: de exemplu DI separat si DO agregat produce iesiri DI individuale plus o iesire agregata pentru DO. Daca DI si DO sunt ambele pe <b>All data on one output</b>, nodul are doua iesiri: prima pentru DI si a doua pentru DO. Aceeasi regula se aplica pentru AI si AO.</p>
|
|
725
|
+
<p>In modul separat, fiecare mesaj are <code>msg.payload</code> cu valoarea canalului, <code>msg.channel</code> numerotat de la 1, <code>msg.channel_index</code> numerotat de la 0 si <code>msg.address</code> cu adresa Modbus manuala.</p>
|
|
726
|
+
|
|
727
|
+
<h3>Familii citite</h3>
|
|
728
|
+
<p>Bifele <b>Read DI</b>, <b>Read DO</b>, <b>Read AI</b> si <b>Read AO</b> controleaza ce familii sunt incluse in payload-ul agregat. Daca o familie este setata pe iesiri separate sau salvare globala, nodul o citeste automat pentru acea functie.</p>
|
|
729
|
+
|
|
730
|
+
<h3>Trigger</h3>
|
|
731
|
+
<p>Cand <b>Poll</b> este o valoare numerica pozitiva, nodul citeste automat si nu are intrare vizibila. Cand <b>Poll</b> este <code>off</code> sau <code>0</code>, nodul afiseaza o intrare si citeste doar cand primeste un mesaj trigger.</p>
|
|
732
|
+
|
|
733
|
+
<h3>Debug output</h3>
|
|
734
|
+
<p><b>Debug output</b> adauga o iesire suplimentara la final. Aceasta iesire trimite payload-ul tehnic complet, cu status, model, count-uri, array-urile brute si numele globale salvate. Daca bifa nu este activa, nodul trimite doar payload-urile de lucru pe familii/canale.</p>
|
|
735
|
+
|
|
736
|
+
<h3>Global context DI / DO / AI / AO</h3>
|
|
737
|
+
<p><b>Save DI globals</b> salveaza fiecare DI in contextul global Node-RED, indiferent daca <b>DI Output</b> este agregat sau separat. Daca <b>DI global names</b> este gol, nodul genereaza automat nume de forma <code>advantech_di1</code>, <code>advantech_di2</code> etc.</p>
|
|
738
|
+
<p><b>Save DO globals</b> functioneaza identic pentru DO, cu nume implicite de forma <code>advantech_do1</code>, <code>advantech_do2</code> etc.</p>
|
|
739
|
+
<p><b>Save AI globals</b> si <b>Save AO globals</b> salveaza valorile analogice numerice in context global, cu nume implicite <code>advantech_ai1</code>, <code>advantech_ai2</code>, <code>advantech_ao1</code>, <code>advantech_ao2</code> etc.</p>
|
|
740
|
+
<p><b>Global prefix</b> schimba baza numelor generate pentru fiecare familie. <b>Global names</b> permite nume custom, cate unul pe linie, in ordinea canalelor.</p>
|
|
741
|
+
|
|
742
|
+
<h3>Adrese implicite</h3>
|
|
743
|
+
<ul>
|
|
744
|
+
<li><code>00001</code> - primul DI coil.</li>
|
|
745
|
+
<li><code>00017</code> - primul DO coil.</li>
|
|
746
|
+
<li><code>40001</code> - primul AI value.</li>
|
|
747
|
+
<li><code>40011</code> - primul AO value pentru ADAM-6024.</li>
|
|
748
|
+
</ul>
|
|
749
|
+
|
|
750
|
+
<h3>Format adrese</h3>
|
|
751
|
+
<p><b>Manual format</b> foloseste adresele asa cum apar in documentatie, de exemplu <code>00017</code> sau <code>40011</code>. <b>Zero-based Modbus offsets</b> foloseste offset-uri Modbus directe, incepand de la <code>0</code>.</p>
|
|
752
|
+
|
|
753
|
+
<h3>Payload agregat</h3>
|
|
754
|
+
<p>In modul <b>All data on one output</b>, fiecare familie trimite un payload plat pe iesirea ei. Exemple:</p>
|
|
755
|
+
<pre>{
|
|
756
|
+
"di1": true,
|
|
757
|
+
"di2": false,
|
|
758
|
+
"di3": true
|
|
759
|
+
}</pre>
|
|
760
|
+
<pre>{
|
|
761
|
+
"do1": false,
|
|
762
|
+
"do2": true
|
|
763
|
+
}</pre>
|
|
764
|
+
<pre>{
|
|
765
|
+
"ai1": 12.4,
|
|
766
|
+
"ai2": 10.8
|
|
767
|
+
}</pre>
|
|
768
|
+
|
|
769
|
+
<h3>Analog</h3>
|
|
770
|
+
<p><b>AI Format</b> poate fi <b>Signed int16 + scale</b> sau <b>IEEE754 float32 pairs</b>. Pentru int16, formula este <code>value = raw * AI Scale + AI Offset</code>. Pentru float32, <b>Float Words</b> controleaza ordinea cuvintelor Modbus.</p>
|
|
771
|
+
<p>AO citit este scalat cu <code>value = raw * AO Scale + AO Offset</code>.</p>
|
|
772
|
+
|
|
773
|
+
<h3>Modele cunoscute</h3>
|
|
774
|
+
<p>Profilele incluse acopera ADAM-6015, 6017, 6018, 6018+, 6022, 6024, 6050, 6051, 6052, 6060 si 6066. Pentru ADAM-6066, profilul este <code>6 DI / 6 DO</code>.</p>
|
|
775
|
+
</script>
|