node-red-contrib-my-tools 1.0.0
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/README.txt +69 -0
- package/node-red-contrib-mysql-extended-test/mysql-extended.html +443 -0
- package/node-red-contrib-mysql-extended-test/mysql-extended.js +355 -0
- package/node-red-contrib-rfid-helper/rfid-lazy.html +153 -0
- package/node-red-contrib-rfid-helper/rfid-lazy.js +361 -0
- package/node-red-contrib-s7-plus/LICENSE +235 -0
- package/node-red-contrib-s7-plus/README.md +141 -0
- package/node-red-contrib-s7-plus/examples/read-multiple-values-flow.json +346 -0
- package/node-red-contrib-s7-plus/examples/read-write-test-flow.json +172 -0
- package/node-red-contrib-s7-plus/examples/write-single-values-flow.json +5583 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/README.md +72 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/areas.js +36 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/datatypes.js +91 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/flat-browser.js +433 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/index.js +22 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/lazy.js +397 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/node-id.js +22 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/resolve-symbolic.js +181 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/vte-helpers.js +49 -0
- package/node-red-contrib-s7-plus/lib/s7plus/buffer-stream.js +96 -0
- package/node-red-contrib-s7-plus/lib/s7plus/client.js +1238 -0
- package/node-red-contrib-s7-plus/lib/s7plus/constants.js +155 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/index.js +3 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/s7-crc32.js +70 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/symbol-crc.js +271 -0
- package/node-red-contrib-s7-plus/lib/s7plus/debug.js +88 -0
- package/node-red-contrib-s7-plus/lib/s7plus/explore-result.js +41 -0
- package/node-red-contrib-s7-plus/lib/s7plus/item-address.js +55 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pdu-explore.js +77 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pdu-messages.js +359 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pobject.js +197 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvalue-codec.js +435 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvalue.js +653 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvar-lists.js +336 -0
- package/node-red-contrib-s7-plus/lib/s7plus/read-result.js +91 -0
- package/node-red-contrib-s7-plus/lib/s7plus/s7p.js +266 -0
- package/node-red-contrib-s7-plus/lib/s7plus/tag-routing.js +30 -0
- package/node-red-contrib-s7-plus/lib/s7plus/transport/cotp-stream.js +335 -0
- package/node-red-contrib-s7-plus/lib/s7plus/transport/s7-transport.js +335 -0
- package/node-red-contrib-s7-plus/nodes/icons/s7complus.png +0 -0
- package/node-red-contrib-s7-plus/nodes/icons/s7complus.svg +17 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-endpoint.js +825 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-explore.js +91 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-in.js +255 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-out.js +182 -0
- package/node-red-contrib-s7-plus/nodes/s7complus.html +1541 -0
- package/node-red-contrib-s7-plus/nodes/s7complus.js +10 -0
- package/node-red-contrib-s7-plus/package.json +50 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Arrays.db +17 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Binary.db +16 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_BitStrings.db +36 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_CharacterStrings.db +42 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_DateAndTime.db +70 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_FloatingPoint.db +42 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Integers.db +72 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Timers.db +40 -0
- package/node-red-contrib-s7-plus/scripts/example-flow-shared.js +39 -0
- package/node-red-contrib-s7-plus/scripts/generate-read-multiple-flow.js +331 -0
- package/node-red-contrib-s7-plus/scripts/generate-rw-test-flow.js +690 -0
- package/node-red-contrib-s7-plus/scripts/generate-write-flow.js +476 -0
- package/node-red-contrib-s7-plus/scripts/layout-write-flow.js +156 -0
- package/node-red-contrib-s7-plus/scripts/run-tests.js +16 -0
- package/node-red-flowgobal-change/variable-change.html +425 -0
- package/node-red-flowgobal-change/variable-change.js +92 -0
- package/node-red-ui_media_viewer/ui_media_viewer.html +87 -0
- package/node-red-ui_media_viewer/ui_media_viewer.js +136 -0
- package/package.json +12 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const S7p = require('./s7p');
|
|
4
|
+
|
|
5
|
+
const TAGDESCR_ATTRIBUTE2_OFFSETINFOTYPE = 0xf000;
|
|
6
|
+
const OFFSETINFOTYPE_FB_ARRAY = 0;
|
|
7
|
+
const OFFSETINFOTYPE_STRUCTELEM_STD = 1;
|
|
8
|
+
const OFFSETINFOTYPE_STD = 8;
|
|
9
|
+
const OFFSETINFOTYPE_STRING = 9;
|
|
10
|
+
const OFFSETINFOTYPE_ARRAY1DIM = 10;
|
|
11
|
+
const OFFSETINFOTYPE_ARRAYMDIM = 11;
|
|
12
|
+
const OFFSETINFOTYPE_STRUCT = 12;
|
|
13
|
+
const OFFSETINFOTYPE_STRUCT1DIM = 13;
|
|
14
|
+
const OFFSETINFOTYPE_STRUCTMDIM = 14;
|
|
15
|
+
const OFFSETINFOTYPE_FBSFB = 15;
|
|
16
|
+
|
|
17
|
+
class POffsetInfoType {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.optimizedAddress = 0;
|
|
20
|
+
this.nonoptimizedAddress = 0;
|
|
21
|
+
}
|
|
22
|
+
hasRelation() { return false; }
|
|
23
|
+
is1Dim() { return false; }
|
|
24
|
+
isMDim() { return false; }
|
|
25
|
+
getRelationId() { return 0; }
|
|
26
|
+
getArrayLowerBounds() { return 0; }
|
|
27
|
+
getArrayElementCount() { return 0; }
|
|
28
|
+
getMdimArrayLowerBounds() { return [0, 0, 0, 0, 0, 0]; }
|
|
29
|
+
getMdimArrayElementCount() { return [0, 0, 0, 0, 0, 0]; }
|
|
30
|
+
|
|
31
|
+
static deserialize(buf, offsetinfotype) {
|
|
32
|
+
switch (offsetinfotype) {
|
|
33
|
+
case OFFSETINFOTYPE_FB_ARRAY:
|
|
34
|
+
return POffsetInfoTypeFbArray.deserialize(buf);
|
|
35
|
+
case OFFSETINFOTYPE_STRUCTELEM_STD:
|
|
36
|
+
case OFFSETINFOTYPE_STD:
|
|
37
|
+
return POffsetInfoTypeStd.deserialize(buf, offsetinfotype);
|
|
38
|
+
case 2: // StructElemString
|
|
39
|
+
case OFFSETINFOTYPE_STRING:
|
|
40
|
+
return POffsetInfoTypeString.deserialize(buf);
|
|
41
|
+
case 3:
|
|
42
|
+
case OFFSETINFOTYPE_ARRAY1DIM:
|
|
43
|
+
return POffsetInfoTypeArray1Dim.deserialize(buf);
|
|
44
|
+
case 4:
|
|
45
|
+
case OFFSETINFOTYPE_ARRAYMDIM:
|
|
46
|
+
return POffsetInfoTypeArrayMDim.deserialize(buf);
|
|
47
|
+
case 5:
|
|
48
|
+
case OFFSETINFOTYPE_STRUCT:
|
|
49
|
+
return POffsetInfoTypeStruct.deserialize(buf);
|
|
50
|
+
case 6:
|
|
51
|
+
case OFFSETINFOTYPE_STRUCT1DIM:
|
|
52
|
+
return POffsetInfoTypeStruct1Dim.deserialize(buf);
|
|
53
|
+
case 7:
|
|
54
|
+
case OFFSETINFOTYPE_STRUCTMDIM:
|
|
55
|
+
return POffsetInfoTypeStructMDim.deserialize(buf);
|
|
56
|
+
case OFFSETINFOTYPE_FBSFB:
|
|
57
|
+
return POffsetInfoTypeFbSfb.deserialize(buf);
|
|
58
|
+
default:
|
|
59
|
+
return { oi: new POffsetInfoType(), n: 0 };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
class POffsetInfoTypeStd extends POffsetInfoType {
|
|
65
|
+
static deserialize(buf, offsetinfotype) {
|
|
66
|
+
const oi = new POffsetInfoTypeStd();
|
|
67
|
+
let r;
|
|
68
|
+
if (offsetinfotype === OFFSETINFOTYPE_STD) {
|
|
69
|
+
r = S7p.decodeUInt16LE(buf);
|
|
70
|
+
oi.optimizedAddress = r.v;
|
|
71
|
+
r = S7p.decodeUInt16LE(buf);
|
|
72
|
+
oi.nonoptimizedAddress = r.v;
|
|
73
|
+
} else {
|
|
74
|
+
r = S7p.decodeUInt16LE(buf);
|
|
75
|
+
oi.nonoptimizedAddress = r.v;
|
|
76
|
+
r = S7p.decodeUInt16LE(buf);
|
|
77
|
+
oi.optimizedAddress = r.v;
|
|
78
|
+
}
|
|
79
|
+
return { oi, n: r.n + (offsetinfotype === OFFSETINFOTYPE_STD ? 2 : 2) };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
class POffsetInfoTypeString extends POffsetInfoType {
|
|
84
|
+
static deserialize(buf) {
|
|
85
|
+
const oi = new POffsetInfoTypeString();
|
|
86
|
+
let n = 0;
|
|
87
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
88
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
89
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
90
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
91
|
+
return { oi, n };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
class POffsetInfoTypeArray1Dim extends POffsetInfoType {
|
|
96
|
+
static deserialize(buf) {
|
|
97
|
+
const oi = new POffsetInfoTypeArray1Dim();
|
|
98
|
+
let n = 0;
|
|
99
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
100
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
101
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
102
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
103
|
+
r = S7p.decodeInt32LE(buf); oi.arrayLowerBounds = r.v; n += r.n;
|
|
104
|
+
r = S7p.decodeUInt32LE(buf); oi.arrayElementCount = r.v; n += r.n;
|
|
105
|
+
oi.is1Dim = () => true;
|
|
106
|
+
oi.getArrayLowerBounds = () => oi.arrayLowerBounds;
|
|
107
|
+
oi.getArrayElementCount = () => oi.arrayElementCount;
|
|
108
|
+
return { oi, n };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
class POffsetInfoTypeArrayMDim extends POffsetInfoType {
|
|
113
|
+
static deserialize(buf) {
|
|
114
|
+
const oi = new POffsetInfoTypeArrayMDim();
|
|
115
|
+
let n = 0;
|
|
116
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
117
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
118
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
119
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
120
|
+
r = S7p.decodeInt32LE(buf); oi.arrayLowerBounds = r.v; n += r.n;
|
|
121
|
+
r = S7p.decodeUInt32LE(buf); oi.arrayElementCount = r.v; n += r.n;
|
|
122
|
+
oi.mdimArrayLowerBounds = [];
|
|
123
|
+
oi.mdimArrayElementCount = [];
|
|
124
|
+
for (let d = 0; d < 6; d++) {
|
|
125
|
+
r = S7p.decodeInt32LE(buf); oi.mdimArrayLowerBounds[d] = r.v; n += r.n;
|
|
126
|
+
}
|
|
127
|
+
for (let d = 0; d < 6; d++) {
|
|
128
|
+
r = S7p.decodeUInt32LE(buf); oi.mdimArrayElementCount[d] = r.v; n += r.n;
|
|
129
|
+
}
|
|
130
|
+
oi.isMDim = () => true;
|
|
131
|
+
oi.getArrayLowerBounds = () => oi.arrayLowerBounds;
|
|
132
|
+
oi.getArrayElementCount = () => oi.arrayElementCount;
|
|
133
|
+
oi.getMdimArrayLowerBounds = () => oi.mdimArrayLowerBounds;
|
|
134
|
+
oi.getMdimArrayElementCount = () => oi.mdimArrayElementCount;
|
|
135
|
+
return { oi, n };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class POffsetInfoTypeStruct extends POffsetInfoType {
|
|
140
|
+
static deserialize(buf) {
|
|
141
|
+
const oi = new POffsetInfoTypeStruct();
|
|
142
|
+
let n = 0;
|
|
143
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
144
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
145
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
146
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
147
|
+
r = S7p.decodeUInt32LE(buf); oi.relationId = r.v; n += r.n;
|
|
148
|
+
for (let i = 0; i < 4; i++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
149
|
+
oi.hasRelation = () => true;
|
|
150
|
+
oi.getRelationId = () => oi.relationId;
|
|
151
|
+
return { oi, n };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class POffsetInfoTypeStruct1Dim extends POffsetInfoType {
|
|
156
|
+
static deserialize(buf) {
|
|
157
|
+
const oi = new POffsetInfoTypeStruct1Dim();
|
|
158
|
+
let n = 0;
|
|
159
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
160
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
161
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
162
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
163
|
+
r = S7p.decodeInt32LE(buf); oi.arrayLowerBounds = r.v; n += r.n;
|
|
164
|
+
r = S7p.decodeUInt32LE(buf); oi.arrayElementCount = r.v; n += r.n;
|
|
165
|
+
r = S7p.decodeUInt32LE(buf); n += r.n;
|
|
166
|
+
r = S7p.decodeUInt32LE(buf); n += r.n;
|
|
167
|
+
r = S7p.decodeUInt32LE(buf); oi.relationId = r.v; n += r.n;
|
|
168
|
+
for (let i = 0; i < 4; i++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
169
|
+
oi.is1Dim = () => true;
|
|
170
|
+
oi.hasRelation = () => true;
|
|
171
|
+
oi.getRelationId = () => oi.relationId;
|
|
172
|
+
oi.getArrayLowerBounds = () => oi.arrayLowerBounds;
|
|
173
|
+
oi.getArrayElementCount = () => oi.arrayElementCount;
|
|
174
|
+
return { oi, n };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
class POffsetInfoTypeStructMDim extends POffsetInfoType {
|
|
179
|
+
static deserialize(buf) {
|
|
180
|
+
const oi = new POffsetInfoTypeStructMDim();
|
|
181
|
+
let n = 0;
|
|
182
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
183
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
184
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
185
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
186
|
+
r = S7p.decodeInt32LE(buf); oi.arrayLowerBounds = r.v; n += r.n;
|
|
187
|
+
r = S7p.decodeUInt32LE(buf); oi.arrayElementCount = r.v; n += r.n;
|
|
188
|
+
oi.mdimArrayLowerBounds = [];
|
|
189
|
+
oi.mdimArrayElementCount = [];
|
|
190
|
+
for (let d = 0; d < 6; d++) {
|
|
191
|
+
r = S7p.decodeInt32LE(buf); oi.mdimArrayLowerBounds[d] = r.v; n += r.n;
|
|
192
|
+
}
|
|
193
|
+
for (let d = 0; d < 6; d++) {
|
|
194
|
+
r = S7p.decodeUInt32LE(buf); oi.mdimArrayElementCount[d] = r.v; n += r.n;
|
|
195
|
+
}
|
|
196
|
+
r = S7p.decodeUInt32LE(buf); n += r.n;
|
|
197
|
+
r = S7p.decodeUInt32LE(buf); n += r.n;
|
|
198
|
+
r = S7p.decodeUInt32LE(buf); oi.relationId = r.v; n += r.n;
|
|
199
|
+
for (let i = 0; i < 4; i++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
200
|
+
oi.isMDim = () => true;
|
|
201
|
+
oi.hasRelation = () => true;
|
|
202
|
+
oi.getRelationId = () => oi.relationId;
|
|
203
|
+
oi.getArrayLowerBounds = () => oi.arrayLowerBounds;
|
|
204
|
+
oi.getArrayElementCount = () => oi.arrayElementCount;
|
|
205
|
+
oi.getMdimArrayLowerBounds = () => oi.mdimArrayLowerBounds;
|
|
206
|
+
oi.getMdimArrayElementCount = () => oi.mdimArrayElementCount;
|
|
207
|
+
return { oi, n };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
class POffsetInfoTypeFbSfb extends POffsetInfoType {
|
|
212
|
+
static deserialize(buf) {
|
|
213
|
+
const oi = new POffsetInfoTypeFbSfb();
|
|
214
|
+
let n = 0;
|
|
215
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
216
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
217
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
218
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
219
|
+
r = S7p.decodeUInt32LE(buf); oi.relationId = r.v; n += r.n;
|
|
220
|
+
for (let i = 0; i < 6; i++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
221
|
+
oi.hasRelation = () => true;
|
|
222
|
+
oi.getRelationId = () => oi.relationId;
|
|
223
|
+
return { oi, n };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
class POffsetInfoTypeFbArray extends POffsetInfoType {
|
|
228
|
+
static deserialize(buf) {
|
|
229
|
+
const oi = new POffsetInfoTypeFbArray();
|
|
230
|
+
let n = 0;
|
|
231
|
+
let r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
232
|
+
r = S7p.decodeUInt16LE(buf); n += r.n;
|
|
233
|
+
r = S7p.decodeUInt32LE(buf); oi.optimizedAddress = r.v; n += r.n;
|
|
234
|
+
r = S7p.decodeUInt32LE(buf); oi.nonoptimizedAddress = r.v; n += r.n;
|
|
235
|
+
r = S7p.decodeUInt32LE(buf); oi.relationId = r.v; n += r.n;
|
|
236
|
+
for (let i = 0; i < 10; i++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
237
|
+
for (let d = 0; d < 6; d++) { r = S7p.decodeInt32LE(buf); n += r.n; }
|
|
238
|
+
for (let d = 0; d < 6; d++) { r = S7p.decodeUInt32LE(buf); n += r.n; }
|
|
239
|
+
oi.hasRelation = () => true;
|
|
240
|
+
oi.getRelationId = () => oi.relationId;
|
|
241
|
+
return { oi, n };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
class PVartypeListElement {
|
|
246
|
+
constructor() {
|
|
247
|
+
this.lid = 0;
|
|
248
|
+
this.symbolCrc = 0;
|
|
249
|
+
this.softdatatype = 0;
|
|
250
|
+
this.attributeFlags = 0;
|
|
251
|
+
this.bitoffsetinfoFlags = 0;
|
|
252
|
+
this.offsetInfoType = new POffsetInfoType();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
deserialize(buf) {
|
|
256
|
+
let n = 0;
|
|
257
|
+
let r = S7p.decodeUInt32LE(buf); this.lid = r.v; n += r.n;
|
|
258
|
+
r = S7p.decodeUInt32LE(buf); this.symbolCrc = r.v; n += r.n;
|
|
259
|
+
r = S7p.decodeByte(buf); this.softdatatype = r.v; n += r.n;
|
|
260
|
+
r = S7p.decodeUInt16(buf); this.attributeFlags = r.v; n += r.n;
|
|
261
|
+
const offsetinfotype = (this.attributeFlags & TAGDESCR_ATTRIBUTE2_OFFSETINFOTYPE) >> 12;
|
|
262
|
+
r = S7p.decodeByte(buf); this.bitoffsetinfoFlags = r.v; n += r.n;
|
|
263
|
+
const des = POffsetInfoType.deserialize(buf, offsetinfotype);
|
|
264
|
+
this.offsetInfoType = des.oi;
|
|
265
|
+
n += des.n;
|
|
266
|
+
return n;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
class PVartypeList {
|
|
271
|
+
constructor() {
|
|
272
|
+
this.elements = [];
|
|
273
|
+
this.firstId = 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
deserialize(buf) {
|
|
277
|
+
let n = 0;
|
|
278
|
+
let r = S7p.decodeUInt16(buf);
|
|
279
|
+
let blocklen = r.v;
|
|
280
|
+
n += r.n;
|
|
281
|
+
let maxret = n + blocklen;
|
|
282
|
+
r = S7p.decodeUInt32LE(buf);
|
|
283
|
+
this.firstId = r.v;
|
|
284
|
+
n += r.n;
|
|
285
|
+
while (blocklen > 0) {
|
|
286
|
+
do {
|
|
287
|
+
const elem = new PVartypeListElement();
|
|
288
|
+
n += elem.deserialize(buf);
|
|
289
|
+
this.elements.push(elem);
|
|
290
|
+
} while (n < maxret);
|
|
291
|
+
r = S7p.decodeUInt16(buf);
|
|
292
|
+
blocklen = r.v;
|
|
293
|
+
n += r.n;
|
|
294
|
+
maxret = n + blocklen;
|
|
295
|
+
}
|
|
296
|
+
return n;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
class PVarnameList {
|
|
301
|
+
constructor() {
|
|
302
|
+
this.names = [];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
deserialize(buf) {
|
|
306
|
+
let n = 0;
|
|
307
|
+
let r = S7p.decodeUInt16(buf);
|
|
308
|
+
let blocklen = r.v;
|
|
309
|
+
n += r.n;
|
|
310
|
+
let maxret = n + blocklen;
|
|
311
|
+
while (blocklen > 0) {
|
|
312
|
+
do {
|
|
313
|
+
r = S7p.decodeByte(buf);
|
|
314
|
+
const namelen = r.v;
|
|
315
|
+
n += r.n;
|
|
316
|
+
r = S7p.decodeWString(buf, namelen);
|
|
317
|
+
this.names.push(r.v);
|
|
318
|
+
n += r.n;
|
|
319
|
+
r = S7p.decodeByte(buf);
|
|
320
|
+
n += r.n;
|
|
321
|
+
} while (n < maxret);
|
|
322
|
+
r = S7p.decodeUInt16(buf);
|
|
323
|
+
blocklen = r.v;
|
|
324
|
+
n += r.n;
|
|
325
|
+
maxret = n + blocklen;
|
|
326
|
+
}
|
|
327
|
+
return n;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
module.exports = {
|
|
332
|
+
PVartypeList,
|
|
333
|
+
PVartypeListElement,
|
|
334
|
+
PVarnameList,
|
|
335
|
+
POffsetInfoType
|
|
336
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { errorText, S7Consts } = require('./constants');
|
|
4
|
+
|
|
5
|
+
function readTagErrorText(err) {
|
|
6
|
+
if (!err || err === 0n) return 'OK';
|
|
7
|
+
if (err <= BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
8
|
+
const n = Number(err);
|
|
9
|
+
const text = errorText(n);
|
|
10
|
+
if (text !== `CLI: Unknown error (0x${(n >>> 0).toString(16)})`) {
|
|
11
|
+
return text;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return `PLC: Read error (0x${err.toString(16)})`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function buildReadTagStatus(err) {
|
|
18
|
+
if (!err || err === 0n) {
|
|
19
|
+
return { status: 'ok', error: '' };
|
|
20
|
+
}
|
|
21
|
+
return { status: 'error', error: readTagErrorText(err) };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function writeTagErrorText(err) {
|
|
25
|
+
if (!err || err === 0n) return 'OK';
|
|
26
|
+
if (err <= BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
27
|
+
const n = Number(err);
|
|
28
|
+
const text = errorText(n);
|
|
29
|
+
if (text !== `CLI: Unknown error (0x${(n >>> 0).toString(16)})`) {
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return `PLC: Write error (0x${err.toString(16)})`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function buildReadPayload(prepared, rawValues, errors, decodeReadValue) {
|
|
37
|
+
const result = {};
|
|
38
|
+
for (let i = 0; i < prepared.length; i++) {
|
|
39
|
+
const name = prepared[i].tag.name || `tag${i}`;
|
|
40
|
+
const err = errors[i];
|
|
41
|
+
const tagStatus = buildReadTagStatus(err);
|
|
42
|
+
if (tagStatus.status === 'ok') {
|
|
43
|
+
const softdatatype = prepared[i].tag.datatype || undefined;
|
|
44
|
+
result[name] = { value: decodeReadValue(rawValues[i], softdatatype), ...tagStatus };
|
|
45
|
+
} else {
|
|
46
|
+
result[name] = { value: null, ...tagStatus };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function buildWriteTagStatus(err) {
|
|
53
|
+
if (!err || err === 0n) {
|
|
54
|
+
return { status: 'ok', error: '' };
|
|
55
|
+
}
|
|
56
|
+
return { status: 'error', error: writeTagErrorText(err) };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Build a per-tag write result keyed by tag name, mirroring buildReadPayload.
|
|
61
|
+
* On success the written value is echoed back; on error the value is null,
|
|
62
|
+
* exactly like the read payload.
|
|
63
|
+
*/
|
|
64
|
+
function buildWritePayload(tags, errors) {
|
|
65
|
+
const result = {};
|
|
66
|
+
for (let i = 0; i < tags.length; i++) {
|
|
67
|
+
const name = tags[i].name || `tag${i}`;
|
|
68
|
+
const tagStatus = buildWriteTagStatus(errors[i]);
|
|
69
|
+
result[name] = tagStatus.status === 'ok'
|
|
70
|
+
? { value: tags[i].value, ...tagStatus }
|
|
71
|
+
: { value: null, ...tagStatus };
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function formatOutputPayload(result, order, format) {
|
|
77
|
+
if (format !== 'array') return result;
|
|
78
|
+
return order
|
|
79
|
+
.filter((symbol) => Object.prototype.hasOwnProperty.call(result, symbol))
|
|
80
|
+
.map((symbol) => ({ symbol, ...result[symbol] }));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = {
|
|
84
|
+
readTagErrorText,
|
|
85
|
+
writeTagErrorText,
|
|
86
|
+
buildReadTagStatus,
|
|
87
|
+
buildReadPayload,
|
|
88
|
+
buildWriteTagStatus,
|
|
89
|
+
buildWritePayload,
|
|
90
|
+
formatOutputPayload
|
|
91
|
+
};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Ids } = require('./constants');
|
|
4
|
+
|
|
5
|
+
const S7p = {
|
|
6
|
+
encodeByte(buf, v) { return buf.writeByte(v); },
|
|
7
|
+
encodeUInt16(buf, v) {
|
|
8
|
+
buf.writeByte((v & 0xff00) >> 8);
|
|
9
|
+
buf.writeByte(v & 0xff);
|
|
10
|
+
return 2;
|
|
11
|
+
},
|
|
12
|
+
encodeUInt32(buf, v) {
|
|
13
|
+
buf.writeByte((v >>> 24) & 0xff);
|
|
14
|
+
buf.writeByte((v >>> 16) & 0xff);
|
|
15
|
+
buf.writeByte((v >>> 8) & 0xff);
|
|
16
|
+
buf.writeByte(v & 0xff);
|
|
17
|
+
return 4;
|
|
18
|
+
},
|
|
19
|
+
encodeUInt64(buf, v) {
|
|
20
|
+
const n = BigInt(v);
|
|
21
|
+
// Unsigned 64-bit wire field: a negative or oversized value would be
|
|
22
|
+
// silently re-encoded as its two's-complement bit pattern (e.g. a
|
|
23
|
+
// pre-1970 LDT turning into year 2554). Reject it loudly instead.
|
|
24
|
+
if (n < 0n || n > 0xffffffffffffffffn) {
|
|
25
|
+
throw new Error(`encodeUInt64: value ${n} out of unsigned 64-bit range (0 .. 2^64-1)`);
|
|
26
|
+
}
|
|
27
|
+
const hi = Number((n >> 32n) & 0xffffffffn);
|
|
28
|
+
const lo = Number(n & 0xffffffffn);
|
|
29
|
+
S7p.encodeUInt32(buf, hi);
|
|
30
|
+
S7p.encodeUInt32(buf, lo);
|
|
31
|
+
return 8;
|
|
32
|
+
},
|
|
33
|
+
encodeInt32Vlq(buf, value) {
|
|
34
|
+
const b = [];
|
|
35
|
+
let absV;
|
|
36
|
+
if (value === -2147483648) absV = 2147483648;
|
|
37
|
+
else absV = Math.abs(value);
|
|
38
|
+
b[0] = value & 0x7f;
|
|
39
|
+
let length = 1;
|
|
40
|
+
for (let i = 1; i < 5; i++) {
|
|
41
|
+
if (absV >= 0x40) {
|
|
42
|
+
length++;
|
|
43
|
+
absV >>>= 7;
|
|
44
|
+
value >>= 7;
|
|
45
|
+
b[i] = (value & 0x7f) + 0x80;
|
|
46
|
+
} else break;
|
|
47
|
+
}
|
|
48
|
+
for (let i = length - 1; i >= 0; i--) buf.writeByte(b[i]);
|
|
49
|
+
return length;
|
|
50
|
+
},
|
|
51
|
+
encodeUInt32Vlq(buf, value) {
|
|
52
|
+
const bytes = [];
|
|
53
|
+
let i;
|
|
54
|
+
for (i = 4; i > 0; i--) {
|
|
55
|
+
if (value & (0x7f << (i * 7))) break;
|
|
56
|
+
}
|
|
57
|
+
for (let j = 0; j <= i; j++) {
|
|
58
|
+
bytes[j] = ((value >> ((i - j) * 7)) & 0x7f) | 0x80;
|
|
59
|
+
}
|
|
60
|
+
bytes[i] ^= 0x80;
|
|
61
|
+
buf.writeBytes(Buffer.from(bytes.slice(0, i + 1)));
|
|
62
|
+
return i + 1;
|
|
63
|
+
},
|
|
64
|
+
encodeUInt64Vlq(buf, value) {
|
|
65
|
+
const b = [];
|
|
66
|
+
let val = BigInt(value);
|
|
67
|
+
const special = val > 0x00ffffffffffffffn;
|
|
68
|
+
if (special) b[0] = Number(val & 0xffn);
|
|
69
|
+
else b[0] = Number(val & 0x7fn);
|
|
70
|
+
let length = 1;
|
|
71
|
+
for (let i = 1; i < 9; i++) {
|
|
72
|
+
if (val >= 0x80n) {
|
|
73
|
+
length++;
|
|
74
|
+
if (i === 1 && special) val >>= 8n;
|
|
75
|
+
else val >>= 7n;
|
|
76
|
+
b[i] = Number(val & 0x7fn) + 0x80;
|
|
77
|
+
} else break;
|
|
78
|
+
}
|
|
79
|
+
if (special && length === 8) {
|
|
80
|
+
length++;
|
|
81
|
+
b[8] = 0x80;
|
|
82
|
+
}
|
|
83
|
+
for (let i = length - 1; i >= 0; i--) buf.writeByte(b[i]);
|
|
84
|
+
return length;
|
|
85
|
+
},
|
|
86
|
+
encodeFloat(buf, value) {
|
|
87
|
+
const v = Buffer.alloc(4);
|
|
88
|
+
v.writeFloatLE(value, 0);
|
|
89
|
+
buf.writeByte(v[3]);
|
|
90
|
+
buf.writeByte(v[2]);
|
|
91
|
+
buf.writeByte(v[1]);
|
|
92
|
+
buf.writeByte(v[0]);
|
|
93
|
+
return 4;
|
|
94
|
+
},
|
|
95
|
+
encodeDouble(buf, value) {
|
|
96
|
+
const v = Buffer.alloc(8);
|
|
97
|
+
v.writeDoubleLE(value, 0);
|
|
98
|
+
for (let i = 7; i >= 0; i--) buf.writeByte(v[i]);
|
|
99
|
+
return 8;
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
decodeByte(buf) {
|
|
103
|
+
const v = buf.readByte();
|
|
104
|
+
return v === null ? { n: 0, v: 0 } : { n: 1, v };
|
|
105
|
+
},
|
|
106
|
+
decodeUInt16(buf) {
|
|
107
|
+
const a = buf.readByte();
|
|
108
|
+
const b = buf.readByte();
|
|
109
|
+
if (a === null || b === null) return { n: 0, v: 0 };
|
|
110
|
+
return { n: 2, v: (a << 8) | b };
|
|
111
|
+
},
|
|
112
|
+
decodeUInt32(buf) {
|
|
113
|
+
const a = buf.readByte(); const b = buf.readByte();
|
|
114
|
+
const c = buf.readByte(); const d = buf.readByte();
|
|
115
|
+
if (d === null) return { n: 0, v: 0 };
|
|
116
|
+
return { n: 4, v: ((a << 24) | (b << 16) | (c << 8) | d) >>> 0 };
|
|
117
|
+
},
|
|
118
|
+
decodeInt16(buf) {
|
|
119
|
+
const r = S7p.decodeUInt16(buf);
|
|
120
|
+
let v = r.v;
|
|
121
|
+
if (v & 0x8000) v -= 0x10000;
|
|
122
|
+
return { n: r.n, v };
|
|
123
|
+
},
|
|
124
|
+
decodeUInt64(buf) {
|
|
125
|
+
const hi = S7p.decodeUInt32(buf);
|
|
126
|
+
const lo = S7p.decodeUInt32(buf);
|
|
127
|
+
return { n: 8, v: (BigInt(hi.v) << 32n) | BigInt(lo.v) };
|
|
128
|
+
},
|
|
129
|
+
decodeInt64(buf) {
|
|
130
|
+
const r = S7p.decodeUInt64(buf);
|
|
131
|
+
let v = r.v;
|
|
132
|
+
if (v >= 0x8000000000000000n) v -= 0x10000000000000000n;
|
|
133
|
+
return { n: 8, v };
|
|
134
|
+
},
|
|
135
|
+
decodeUInt16LE(buf) {
|
|
136
|
+
const a = buf.readByte(); const b = buf.readByte();
|
|
137
|
+
if (b === null) return { n: 0, v: 0 };
|
|
138
|
+
return { n: 2, v: (a | (b << 8)) & 0xffff };
|
|
139
|
+
},
|
|
140
|
+
decodeUInt32LE(buf) {
|
|
141
|
+
const a = buf.readByte(); const b = buf.readByte();
|
|
142
|
+
const c = buf.readByte(); const d = buf.readByte();
|
|
143
|
+
if (d === null) return { n: 0, v: 0 };
|
|
144
|
+
return { n: 4, v: (a | (b << 8) | (c << 16) | (d << 24)) >>> 0 };
|
|
145
|
+
},
|
|
146
|
+
decodeInt32LE(buf) {
|
|
147
|
+
const r = S7p.decodeUInt32LE(buf);
|
|
148
|
+
let v = r.v;
|
|
149
|
+
if (v & 0x80000000) v = v - 0x100000000;
|
|
150
|
+
return { n: r.n, v };
|
|
151
|
+
},
|
|
152
|
+
decodeWString(buf, len) {
|
|
153
|
+
const bytes = buf.readBytes(len);
|
|
154
|
+
if (!bytes) return { n: 0, v: '' };
|
|
155
|
+
return { n: len, v: bytes.toString('utf8') };
|
|
156
|
+
},
|
|
157
|
+
decodeUInt32Vlq(buf) {
|
|
158
|
+
let val = 0;
|
|
159
|
+
let length = 0;
|
|
160
|
+
for (let counter = 1; counter <= 5; counter++) {
|
|
161
|
+
const octet = buf.readByte();
|
|
162
|
+
if (octet === null) break;
|
|
163
|
+
length++;
|
|
164
|
+
val <<= 7;
|
|
165
|
+
const cont = octet & 0x80;
|
|
166
|
+
val += octet & 0x7f;
|
|
167
|
+
if (cont === 0) break;
|
|
168
|
+
}
|
|
169
|
+
return { n: length, v: val >>> 0 };
|
|
170
|
+
},
|
|
171
|
+
decodeInt32Vlq(buf) {
|
|
172
|
+
let val = 0;
|
|
173
|
+
let length = 0;
|
|
174
|
+
for (let counter = 1; counter <= 5; counter++) {
|
|
175
|
+
let octet = buf.readByte();
|
|
176
|
+
if (octet === null) break;
|
|
177
|
+
length++;
|
|
178
|
+
if (counter === 1 && (octet & 0x40)) {
|
|
179
|
+
octet &= 0xbf;
|
|
180
|
+
val = -64;
|
|
181
|
+
} else val <<= 7;
|
|
182
|
+
const cont = octet & 0x80;
|
|
183
|
+
val += octet & 0x7f;
|
|
184
|
+
if (cont === 0) break;
|
|
185
|
+
}
|
|
186
|
+
return { n: length, v: val | 0 };
|
|
187
|
+
},
|
|
188
|
+
decodeUInt64Vlq(buf) {
|
|
189
|
+
let val = 0n;
|
|
190
|
+
let length = 0;
|
|
191
|
+
let cont = 0;
|
|
192
|
+
let octet = 0;
|
|
193
|
+
for (let counter = 1; counter <= 8; counter++) {
|
|
194
|
+
octet = buf.readByte();
|
|
195
|
+
if (octet === null) break;
|
|
196
|
+
length++;
|
|
197
|
+
val <<= 7n;
|
|
198
|
+
cont = octet & 0x80;
|
|
199
|
+
val += BigInt(octet & 0x7f);
|
|
200
|
+
if (cont === 0) break;
|
|
201
|
+
}
|
|
202
|
+
if (cont > 0) {
|
|
203
|
+
octet = buf.readByte();
|
|
204
|
+
if (octet !== null) {
|
|
205
|
+
length++;
|
|
206
|
+
val <<= 8n;
|
|
207
|
+
val += BigInt(octet);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { n: length, v: val };
|
|
211
|
+
},
|
|
212
|
+
decodeInt64Vlq(buf) {
|
|
213
|
+
let val = 0n;
|
|
214
|
+
let length = 0;
|
|
215
|
+
let cont = 0;
|
|
216
|
+
let octet = 0;
|
|
217
|
+
for (let counter = 1; counter <= 8; counter++) {
|
|
218
|
+
octet = buf.readByte();
|
|
219
|
+
if (octet === null) break;
|
|
220
|
+
length++;
|
|
221
|
+
if (counter === 1 && (octet & 0x40)) {
|
|
222
|
+
octet &= 0xbf;
|
|
223
|
+
val = -64n;
|
|
224
|
+
} else val <<= 7n;
|
|
225
|
+
cont = octet & 0x80;
|
|
226
|
+
val += BigInt(octet & 0x7f);
|
|
227
|
+
if (cont === 0) break;
|
|
228
|
+
}
|
|
229
|
+
if (cont > 0) {
|
|
230
|
+
octet = buf.readByte();
|
|
231
|
+
if (octet !== null) {
|
|
232
|
+
length++;
|
|
233
|
+
val <<= 8n;
|
|
234
|
+
val += BigInt(octet);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return { n: length, v: val };
|
|
238
|
+
},
|
|
239
|
+
decodeFloat(buf) {
|
|
240
|
+
const v = Buffer.alloc(4);
|
|
241
|
+
v[3] = buf.readByte();
|
|
242
|
+
v[2] = buf.readByte();
|
|
243
|
+
v[1] = buf.readByte();
|
|
244
|
+
v[0] = buf.readByte();
|
|
245
|
+
return { n: 4, v: v.readFloatLE(0) };
|
|
246
|
+
},
|
|
247
|
+
decodeDouble(buf) {
|
|
248
|
+
const v = Buffer.alloc(8);
|
|
249
|
+
for (let i = 7; i >= 0; i--) v[i] = buf.readByte();
|
|
250
|
+
return { n: 8, v: v.readDoubleLE(0) };
|
|
251
|
+
},
|
|
252
|
+
decodeHeader(buf) {
|
|
253
|
+
buf.readByte();
|
|
254
|
+
const ver = buf.readByte();
|
|
255
|
+
const len = S7p.decodeUInt16(buf);
|
|
256
|
+
return { version: ver, length: len.v };
|
|
257
|
+
},
|
|
258
|
+
encodeHeader(buf, version, length) {
|
|
259
|
+
buf.writeByte(0x72);
|
|
260
|
+
buf.writeByte(version);
|
|
261
|
+
S7p.encodeUInt16(buf, length);
|
|
262
|
+
return 4;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
module.exports = S7p;
|