@vitormnm/node-red-instructions-ladder-iec-61131-3 1.0.3 → 1.1.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.md +8 -0
- package/instructions_ladder_IEC_61131_3.html +109 -47
- package/instructions_ladder_IEC_61131_3.js +120 -32
- package/instructions_ladder_IEC_61131_3_v1.zip +0 -0
- package/package.json +3 -3
- package/registry.js +17 -0
package/README.md
CHANGED
|
@@ -34,12 +34,20 @@ A Node-RED node that provides common **IEC 61131-3 Ladder Logic instructions** f
|
|
|
34
34
|
| SQR | Square root |
|
|
35
35
|
| MOV | Move value |
|
|
36
36
|
|
|
37
|
+
### counter Instructions
|
|
38
|
+
|
|
39
|
+
| Instruction | Description |
|
|
40
|
+
| ----------- | -------------- |
|
|
41
|
+
| CTU | counter up |
|
|
42
|
+
|
|
43
|
+
|
|
37
44
|
### Output Instructions
|
|
38
45
|
|
|
39
46
|
| Instruction | Description |
|
|
40
47
|
| ----------- | ---------------------------------------- |
|
|
41
48
|
| SET | Sets the destination variable to `true` |
|
|
42
49
|
| RESET | Sets the destination variable to `false` |
|
|
50
|
+
| CTU | OBJ {"Q":true,"CV":15} |
|
|
43
51
|
|
|
44
52
|
---
|
|
45
53
|
|
|
@@ -4,51 +4,66 @@
|
|
|
4
4
|
<script type="text/javascript">
|
|
5
5
|
|
|
6
6
|
var LADDER_META = {
|
|
7
|
-
NO:
|
|
8
|
-
NC:
|
|
9
|
-
EQ:
|
|
10
|
-
NEQ:
|
|
11
|
-
GT:
|
|
12
|
-
GE:
|
|
13
|
-
LT:
|
|
14
|
-
LE:
|
|
15
|
-
ADD:
|
|
16
|
-
SUB:
|
|
17
|
-
MUL:
|
|
18
|
-
DIV:
|
|
19
|
-
MOD:
|
|
20
|
-
MOV:
|
|
21
|
-
ABS:
|
|
22
|
-
SQR:
|
|
23
|
-
SET:
|
|
24
|
-
RESET: { srcA: false, srcB: false, dest: true,
|
|
7
|
+
NO: { srcA: true, srcB: false, dest: false, category: 'Contact' },
|
|
8
|
+
NC: { srcA: true, srcB: false, dest: false, category: 'Contact' },
|
|
9
|
+
EQ: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
10
|
+
NEQ: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
11
|
+
GT: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
12
|
+
GE: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
13
|
+
LT: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
14
|
+
LE: { srcA: true, srcB: true, dest: false, category: 'Compare' },
|
|
15
|
+
ADD: { srcA: true, srcB: true, dest: true, category: 'Math' },
|
|
16
|
+
SUB: { srcA: true, srcB: true, dest: true, category: 'Math' },
|
|
17
|
+
MUL: { srcA: true, srcB: true, dest: true, category: 'Math' },
|
|
18
|
+
DIV: { srcA: true, srcB: true, dest: true, category: 'Math' },
|
|
19
|
+
MOD: { srcA: true, srcB: true, dest: true, category: 'Math' },
|
|
20
|
+
MOV: { srcA: true, srcB: false, dest: true, category: 'Math' },
|
|
21
|
+
ABS: { srcA: true, srcB: false, dest: true, category: 'Math' },
|
|
22
|
+
SQR: { srcA: true, srcB: false, dest: true, category: 'Math' },
|
|
23
|
+
SET: { srcA: false, srcB: false, dest: true, category: 'Coil' },
|
|
24
|
+
RESET: { srcA: false, srcB: false, dest: true, category: 'Coil' },
|
|
25
|
+
CTU: { srcA: true, srcB: true, srcC: true, dest: true, category: 'Counter' }
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
RED.nodes.registerType('instructions-ladder-
|
|
28
|
-
category:
|
|
29
|
-
color:
|
|
28
|
+
RED.nodes.registerType('instructions-ladder-iec-61131-3', {
|
|
29
|
+
category: 'function',
|
|
30
|
+
color: '#C0392B',
|
|
30
31
|
defaults: {
|
|
31
|
-
name:
|
|
32
|
+
name: { value: '' },
|
|
32
33
|
ladderFunc: { value: 'NO' },
|
|
33
|
-
srcA:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
34
|
+
srcA: {
|
|
35
|
+
value: 'payload', validate: function (v) {
|
|
36
|
+
var meta = LADDER_META[$('#node-input-ladderFunc').val()] || {};
|
|
37
|
+
return !meta.srcA || (v !== undefined && v !== '');
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
srcAType: { value: 'msg' },
|
|
41
|
+
srcB: {
|
|
42
|
+
value: 'payload', validate: function (v) {
|
|
43
|
+
var meta = LADDER_META[$('#node-input-ladderFunc').val()] || {};
|
|
44
|
+
return !meta.srcB || (v !== undefined && v !== '');
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
srcBType: { value: 'msg' },
|
|
48
|
+
srcC: {
|
|
49
|
+
value: 'payload', validate: function (v) {
|
|
50
|
+
var meta = LADDER_META[$('#node-input-ladderFunc').val()] || {};
|
|
51
|
+
return !meta.srcC || (v !== undefined && v !== '');
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
srcCType: { value: 'msg' },
|
|
55
|
+
dest: {
|
|
56
|
+
value: 'payload', validate: function (v) {
|
|
57
|
+
var meta = LADDER_META[$('#node-input-ladderFunc').val()] || {};
|
|
58
|
+
return !meta.dest || (v !== undefined && v !== '');
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
destType: { value: 'msg' },
|
|
62
|
+
|
|
48
63
|
},
|
|
49
|
-
inputs:
|
|
64
|
+
inputs: 1,
|
|
50
65
|
outputs: 1,
|
|
51
|
-
icon:
|
|
66
|
+
icon: 'ladder.svg',
|
|
52
67
|
paletteLabel: 'ladder iec',
|
|
53
68
|
|
|
54
69
|
label: function () {
|
|
@@ -68,18 +83,55 @@
|
|
|
68
83
|
typeField: '#node-input-srcBType',
|
|
69
84
|
types: ['msg', 'flow', 'global', 'num', 'bool', 'str']
|
|
70
85
|
});
|
|
86
|
+
$('#node-input-srcC').typedInput({
|
|
87
|
+
typeField: '#node-input-srcCType',
|
|
88
|
+
types: ['msg', 'flow', 'global', 'num', 'bool', 'str']
|
|
89
|
+
});
|
|
90
|
+
|
|
71
91
|
$('#node-input-dest').typedInput({
|
|
72
92
|
typeField: '#node-input-destType',
|
|
73
93
|
types: ['msg', 'flow', 'global']
|
|
74
94
|
});
|
|
75
95
|
|
|
96
|
+
|
|
76
97
|
function updateFields() {
|
|
77
|
-
var fn
|
|
98
|
+
var fn = $('#node-input-ladderFunc').val();
|
|
78
99
|
var meta = LADDER_META[fn] || {};
|
|
100
|
+
|
|
79
101
|
$('#row-srcA').toggle(!!meta.srcA);
|
|
80
102
|
$('#row-srcB').toggle(!!meta.srcB);
|
|
103
|
+
$('#row-srcC').toggle(!!meta.srcC);
|
|
81
104
|
$('#row-dest').toggle(!!meta.dest);
|
|
105
|
+
$('#row-destB').toggle(!!meta.destB);
|
|
82
106
|
$('#ladder-category').text(meta.category ? '[' + meta.category + ']' : '');
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
if (fn === "CTU") {
|
|
110
|
+
|
|
111
|
+
$("label[for='node-input-srcA']").html(
|
|
112
|
+
'<i class="fa fa-arrow-right"></i> CU'
|
|
113
|
+
);
|
|
114
|
+
$("label[for='node-input-srcB']").html(
|
|
115
|
+
'<i class="fa fa-arrow-right"></i> RESET'
|
|
116
|
+
);
|
|
117
|
+
$("label[for='node-input-srcC']").html(
|
|
118
|
+
'<i class="fa fa-arrow-right"></i> PV'
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
} else {
|
|
122
|
+
|
|
123
|
+
$("label[for='node-input-srcA']").html(
|
|
124
|
+
'<i class="fa fa-arrow-right"></i> Source A'
|
|
125
|
+
);
|
|
126
|
+
$("label[for='node-input-srcB']").html(
|
|
127
|
+
'<i class="fa fa-arrow-right"></i> Source B'
|
|
128
|
+
);
|
|
129
|
+
$("label[for='node-input-srcC']").html(
|
|
130
|
+
'<i class="fa fa-arrow-right"></i> Source C'
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
83
135
|
}
|
|
84
136
|
|
|
85
137
|
$('#node-input-ladderFunc').on('change', updateFields);
|
|
@@ -91,7 +143,7 @@
|
|
|
91
143
|
<!-- ═══════════════════════════════════════════════════════════════════════
|
|
92
144
|
Edit Dialog
|
|
93
145
|
═══════════════════════════════════════════════════════════════════════ -->
|
|
94
|
-
<script type="text/html" data-template-name="instructions-ladder-
|
|
146
|
+
<script type="text/html" data-template-name="instructions-ladder-iec-61131-3">
|
|
95
147
|
|
|
96
148
|
<div class="form-row">
|
|
97
149
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
@@ -103,11 +155,11 @@
|
|
|
103
155
|
<div class="form-row">
|
|
104
156
|
<label for="node-input-ladderFunc"><i class="fa fa-microchip"></i> Instruction</label>
|
|
105
157
|
<select id="node-input-ladderFunc" style="width:70%;">
|
|
106
|
-
<optgroup label="
|
|
158
|
+
<optgroup label="Contacts ">
|
|
107
159
|
<option value="NO">-||- Normally Open Contact </option>
|
|
108
160
|
<option value="NC">-|/|- Normally Closed Contact</option>
|
|
109
161
|
</optgroup>
|
|
110
|
-
<optgroup label="
|
|
162
|
+
<optgroup label="Comparators ">
|
|
111
163
|
<option value="EQ">EQ – EQal (A == B)</option>
|
|
112
164
|
<option value="NEQ">NEQ – Not EQal (A != B)</option>
|
|
113
165
|
<option value="GT">GT – Greater Than (A > B)</option>
|
|
@@ -115,7 +167,7 @@
|
|
|
115
167
|
<option value="LT">LT – LTs Than (A < B)</option>
|
|
116
168
|
<option value="LE">LE – LTs or EQal (A <= B)</option>
|
|
117
169
|
</optgroup>
|
|
118
|
-
<optgroup label="
|
|
170
|
+
<optgroup label="Math ">
|
|
119
171
|
<option value="ADD">ADD – Add (A + B → dest)</option>
|
|
120
172
|
<option value="SUB">SUB – Subtract (A - B → dest)</option>
|
|
121
173
|
<option value="MUL">MUL – Multiply (A * B → dest)</option>
|
|
@@ -125,9 +177,11 @@
|
|
|
125
177
|
<option value="ABS">ABS – Absolute Value (|A| → dest)</option>
|
|
126
178
|
<option value="SQR">SQR – Square Root (√A → dest)</option>
|
|
127
179
|
</optgroup>
|
|
128
|
-
<optgroup label="
|
|
180
|
+
<optgroup label="Output Coils ">
|
|
129
181
|
<option value="SET">-(S)- Set/Latch</option>
|
|
130
182
|
<option value="RESET">-(R)- Reset/Unlatch</option>
|
|
183
|
+
<optgroup label="Counter ">
|
|
184
|
+
<option value="CTU">CTU</option>
|
|
131
185
|
</optgroup>
|
|
132
186
|
</select>
|
|
133
187
|
<span id="ladder-category" style="margin-left:8px; color:#999; font-size:0.85em;"></span>
|
|
@@ -147,12 +201,20 @@
|
|
|
147
201
|
<input type="text" id="node-input-srcB" style="width:60%;">
|
|
148
202
|
</div>
|
|
149
203
|
|
|
204
|
+
<div class="form-row" id="row-srcC">
|
|
205
|
+
<label for="node-input-srcC"><i class="fa fa-arrow-right"></i> Source C</label>
|
|
206
|
+
<input type="hidden" id="node-input-srcCType">
|
|
207
|
+
<input type="text" id="node-input-srcC" style="width:60%;">
|
|
208
|
+
</div>
|
|
209
|
+
|
|
150
210
|
<div class="form-row" id="row-dest">
|
|
151
211
|
<label for="node-input-dest"><i class="fa fa-arrow-left"></i> Destination</label>
|
|
152
212
|
<input type="hidden" id="node-input-destType">
|
|
153
213
|
<input type="text" id="node-input-dest" style="width:60%;">
|
|
154
214
|
</div>
|
|
155
215
|
|
|
216
|
+
|
|
217
|
+
|
|
156
218
|
<hr/>
|
|
157
219
|
|
|
158
220
|
<div class="form-row" style="color:#888; font-size:0.85em;">
|
|
@@ -167,7 +229,7 @@
|
|
|
167
229
|
<!-- ═══════════════════════════════════════════════════════════════════════
|
|
168
230
|
Help Panel
|
|
169
231
|
═══════════════════════════════════════════════════════════════════════ -->
|
|
170
|
-
<script type="text/html" data-help-name="instructions-ladder-
|
|
232
|
+
<script type="text/html" data-help-name="instructions-ladder-iec-61131-3">
|
|
171
233
|
<p>
|
|
172
234
|
Simulates <strong>Ladder Logic</strong> instructions from
|
|
173
235
|
<em>Studio 5000 Logix Designer</em> (Rockwell Automation) inside Node-RED.
|
|
@@ -215,4 +277,4 @@
|
|
|
215
277
|
<em>Right</em>: resolved values + result.<br><br>
|
|
216
278
|
🟢 Green dot = TRUE | ⚫ Grey ring = FALSE | 🔴 Red = Error
|
|
217
279
|
</p>
|
|
218
|
-
</script>
|
|
280
|
+
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = function (RED) {
|
|
2
|
-
|
|
2
|
+
const registry = require("./registry");
|
|
3
3
|
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
5
|
function resolveValue(node, msg, type, key) {
|
|
@@ -57,41 +57,75 @@ module.exports = function (RED) {
|
|
|
57
57
|
const vB = fmt(valB);
|
|
58
58
|
const res = result ? 'TRUE' : 'FALSE';
|
|
59
59
|
|
|
60
|
+
let fill
|
|
61
|
+
let shape
|
|
62
|
+
let text = `${fn} executed`;
|
|
63
|
+
|
|
60
64
|
// ── Contacts ─────────────────────────────────────────────────────────
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
if (fn === 'NO' || fn === 'NC') {
|
|
66
|
+
text = `${fn} ${nA}(${vA})→${res}`;
|
|
67
|
+
}
|
|
64
68
|
|
|
65
69
|
// ── Comparators ──────────────────────────────────────────────────────
|
|
66
|
-
// GT temp(85)>limit(80)→TRUE
|
|
67
70
|
const OPS = { EQ: '==', NEQ: '!=', GT: '>', GE: '>=', LT: '<', LE: '<=' };
|
|
68
|
-
if (OPS[fn])
|
|
69
|
-
|
|
71
|
+
if (OPS[fn]) {
|
|
72
|
+
text = `${fn} ${nA}(${vA})${OPS[fn]}${nB}(${vB})→${res}`;
|
|
73
|
+
}
|
|
70
74
|
|
|
71
75
|
// ── Math (two operands) ───────────────────────────────────────────────
|
|
72
|
-
// ADD a(10)+b(5)→result=15
|
|
73
|
-
// DIV x(9)/y(0)→÷0ERR
|
|
74
76
|
const MATH2 = { ADD: '+', SUB: '-', MUL: '*', DIV: '/', MOD: '%' };
|
|
75
77
|
if (MATH2[fn]) {
|
|
76
|
-
if ((fn === 'DIV' || fn === 'MOD') && Number(valB) === 0)
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
if ((fn === 'DIV' || fn === 'MOD') && Number(valB) === 0) {
|
|
79
|
+
text = `${fn} ${nA}(${vA})${MATH2[fn]}${nB}(0)→÷0ERR`;
|
|
80
|
+
} else {
|
|
81
|
+
text = `${fn} ${nA}(${vA})${MATH2[fn]}${nB}(${vB})→${nD}=${fmt(computed)}`;
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
// ── Math (one operand) ────────────────────────────────────────────────
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (fn === 'ABS')
|
|
87
|
-
|
|
86
|
+
if (fn === 'MOV') {
|
|
87
|
+
text = `MOV ${nA}(${vA})→${nD}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (fn === 'ABS') {
|
|
91
|
+
text = `ABS |${nA}(${vA})|→${nD}=${fmt(computed)}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (fn === 'SQR') {
|
|
95
|
+
text = `SQR √${nA}(${vA})→${nD}=${fmt(computed)}`;
|
|
96
|
+
}
|
|
88
97
|
|
|
89
98
|
// ── Output Coils ──────────────────────────────────────────────────────
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
if (fn === 'SET') {
|
|
100
|
+
text = `SET →${nD}=TRUE`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (fn === 'RESET') {
|
|
104
|
+
text = `RST →${nD}=FALSE`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (fn === 'CTU') {
|
|
108
|
+
text = `CTU→CV(${result.CV})=${result.Q}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//Build color
|
|
112
|
+
if (fn == "CTU") {
|
|
113
|
+
fill = result.Q ? 'green' : 'grey';
|
|
114
|
+
shape = result.Q ? 'dot' : 'ring';
|
|
115
|
+
|
|
116
|
+
} else {
|
|
117
|
+
fill = result ? 'green' : 'grey';
|
|
118
|
+
shape = result ? 'dot' : 'ring';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
93
123
|
|
|
94
|
-
return
|
|
124
|
+
return {
|
|
125
|
+
text: text,
|
|
126
|
+
fill: fill,
|
|
127
|
+
shape: shape
|
|
128
|
+
}
|
|
95
129
|
}
|
|
96
130
|
|
|
97
131
|
// ─── Instruction Execution ────────────────────────────────────────────────
|
|
@@ -101,13 +135,20 @@ module.exports = function (RED) {
|
|
|
101
135
|
const fn = config.ladderFunc;
|
|
102
136
|
const valA = resolveValue(node, msg, config.srcAType, config.srcA);
|
|
103
137
|
const valB = resolveValue(node, msg, config.srcBType, config.srcB);
|
|
138
|
+
const valC = resolveValue(node, msg, config.srcCType, config.srcC);
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
104
142
|
const nameA = config.srcA || '';
|
|
105
143
|
const nameB = config.srcB || '';
|
|
106
|
-
const
|
|
144
|
+
const nameC = config.srcC || '';
|
|
107
145
|
|
|
146
|
+
const nameDest = config.dest || '';
|
|
147
|
+
const nameDestB = config.destB || '';
|
|
108
148
|
|
|
109
149
|
let payload = null;
|
|
110
150
|
let result = false;
|
|
151
|
+
let resultB = false;
|
|
111
152
|
let sendMsg = true;
|
|
112
153
|
let Msg = true;
|
|
113
154
|
let computed; // for math instructions that produce a new value
|
|
@@ -184,6 +225,50 @@ module.exports = function (RED) {
|
|
|
184
225
|
case 'RESET':
|
|
185
226
|
result = false;
|
|
186
227
|
resultOperation = true
|
|
228
|
+
break;
|
|
229
|
+
|
|
230
|
+
case 'CTU':
|
|
231
|
+
// SET VALUE
|
|
232
|
+
var memory = registry.getMemory(node)
|
|
233
|
+
if (valA === true) {
|
|
234
|
+
var memory = registry.getMemory(node)
|
|
235
|
+
//Set memory
|
|
236
|
+
if (memory) {
|
|
237
|
+
memory = memory + 1
|
|
238
|
+
registry.setMemory(node, memory)
|
|
239
|
+
} else {
|
|
240
|
+
memory = 1
|
|
241
|
+
registry.setMemory(node, memory)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if(memory === undefined){
|
|
246
|
+
memory = 0;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
//RESET
|
|
250
|
+
if (valB === true) {
|
|
251
|
+
memory = 0
|
|
252
|
+
registry.setMemory(node, memory)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
//set result
|
|
257
|
+
if (memory >= valC) {
|
|
258
|
+
result = {
|
|
259
|
+
Q: true,
|
|
260
|
+
CV: memory
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
resultOperation = true
|
|
264
|
+
|
|
265
|
+
} else {
|
|
266
|
+
resultOperation = true
|
|
267
|
+
result = {
|
|
268
|
+
Q: false,
|
|
269
|
+
CV: memory
|
|
270
|
+
}
|
|
271
|
+
}
|
|
187
272
|
|
|
188
273
|
break;
|
|
189
274
|
|
|
@@ -192,16 +277,17 @@ module.exports = function (RED) {
|
|
|
192
277
|
result = false;
|
|
193
278
|
}
|
|
194
279
|
|
|
195
|
-
const
|
|
196
|
-
return { result, resultOperation,
|
|
280
|
+
const statusConfig = buildStatus(fn, nameA, nameB, nameDest, valA, valB, result, computed);
|
|
281
|
+
return { result, resultOperation, statusConfig, sendMsg };
|
|
197
282
|
}
|
|
198
283
|
|
|
199
284
|
function writeNode(node, msg, config, sendMsg, result, resultOperation) {
|
|
200
285
|
|
|
286
|
+
|
|
201
287
|
const ladderFunc = config.ladderFunc;
|
|
202
288
|
const dest = config.dest;
|
|
203
289
|
const destType = config.destType;
|
|
204
|
-
|
|
290
|
+
|
|
205
291
|
switch (destType) {
|
|
206
292
|
case 'msg':
|
|
207
293
|
if (resultOperation) {
|
|
@@ -219,6 +305,8 @@ module.exports = function (RED) {
|
|
|
219
305
|
}
|
|
220
306
|
}
|
|
221
307
|
|
|
308
|
+
|
|
309
|
+
|
|
222
310
|
// ─── Node Definition ──────────────────────────────────────────────────────
|
|
223
311
|
|
|
224
312
|
function instructions_ladder_IEC_61131_3(config) {
|
|
@@ -229,15 +317,15 @@ module.exports = function (RED) {
|
|
|
229
317
|
|
|
230
318
|
node.on('input', function (msg) {
|
|
231
319
|
try {
|
|
232
|
-
const { result, resultOperation,
|
|
320
|
+
const { result, resultOperation, statusConfig, sendMsg } = executeLadder(node, msg, config);
|
|
233
321
|
|
|
234
322
|
node.status({
|
|
235
|
-
fill:
|
|
236
|
-
shape:
|
|
237
|
-
text:
|
|
323
|
+
fill: statusConfig.fill,
|
|
324
|
+
shape: statusConfig.shape,
|
|
325
|
+
text: statusConfig.text,
|
|
238
326
|
});
|
|
239
327
|
|
|
240
|
-
msg.ladder = { func: config.ladderFunc, result, status:
|
|
328
|
+
msg.ladder = { func: config.ladderFunc, result, status: statusConfig };
|
|
241
329
|
//Write payload and msg
|
|
242
330
|
writeNode(node, msg, config, sendMsg, result, resultOperation)
|
|
243
331
|
|
|
@@ -251,5 +339,5 @@ module.exports = function (RED) {
|
|
|
251
339
|
node.on('close', function () { node.status({}); });
|
|
252
340
|
}
|
|
253
341
|
|
|
254
|
-
RED.nodes.registerType('instructions-ladder-
|
|
342
|
+
RED.nodes.registerType('instructions-ladder-iec-61131-3', instructions_ladder_IEC_61131_3);
|
|
255
343
|
};
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitormnm/node-red-instructions-ladder-iec-61131-3",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"codesys"
|
|
14
14
|
],
|
|
15
15
|
"node-red": {
|
|
16
|
-
"nodes": {
|
|
17
16
|
"version": ">=2.0.0",
|
|
18
|
-
|
|
17
|
+
"nodes": {
|
|
18
|
+
"instructions-ladder-iec-61131-3": "instructions_ladder_IEC_61131_3.js"
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"author": {
|
package/registry.js
ADDED