@flowfuse/nr-project-nodes 0.4.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/.eslintrc +19 -0
- package/.github/workflows/build.yml +25 -0
- package/.github/workflows/project-automation.yml +10 -0
- package/.github/workflows/publish.yml +66 -0
- package/.github/workflows/release-publish.yml +19 -0
- package/CHANGELOG.md +31 -0
- package/LICENSE +203 -0
- package/README.md +49 -0
- package/nodes/icons/ff-logo.svg +6 -0
- package/nodes/project-link.html +475 -0
- package/nodes/project-link.js +936 -0
- package/package.json +37 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
#dialog-form > div.form-row > .ff-project-link-input-width {
|
|
3
|
+
width: calc(100% - 125px);
|
|
4
|
+
}
|
|
5
|
+
#dialog-form > div.form-row > span.ff-project-link-group-option > input {
|
|
6
|
+
width: auto;
|
|
7
|
+
display: inline-block;
|
|
8
|
+
vertical-align: middle;
|
|
9
|
+
margin: 0px 2px 2px 0px;
|
|
10
|
+
}
|
|
11
|
+
#dialog-form > div.form-row > span.ff-project-link-group-option > label {
|
|
12
|
+
width: 250px;
|
|
13
|
+
display: inline-block;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<script type="text/html" data-template-name="project link in">
|
|
18
|
+
<div class="form-row">
|
|
19
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name">Name</span></label>
|
|
20
|
+
<input type="text" id="node-input-name" class="ff-project-link-input-width">
|
|
21
|
+
</div>
|
|
22
|
+
<div class="form-row ff-project-link-list-row">
|
|
23
|
+
<label><i class="fa fa-sign-in"></i> <span>Source</span></label>
|
|
24
|
+
<span class="ff-project-link-group-option">
|
|
25
|
+
<input type="radio" id="ff-project-link-radio-input-direct" name="ff-project-link-broadcast" value="false" checked />
|
|
26
|
+
<label for="ff-project-link-radio-input-direct">Receive messages sent to this instance</label>
|
|
27
|
+
</span>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="form-row ff-project-link-list-row">
|
|
30
|
+
<label><span> </span></label>
|
|
31
|
+
<span class="ff-project-link-group-option">
|
|
32
|
+
<input type="radio" id="ff-project-link-radio-input-broadcast" name="ff-project-link-broadcast" value="true" />
|
|
33
|
+
<label for="ff-project-link-radio-input-broadcast">Listen for broadcast messages from</label>
|
|
34
|
+
</span>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="form-row ff-project-link-list-row">
|
|
37
|
+
<label><span> </span></label>
|
|
38
|
+
<select id="node-input-projectList" class="ff-project-link-input-width" disabled>
|
|
39
|
+
</select>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="form-row">
|
|
42
|
+
<label for="node-input-topic"><i class="fa fa-ellipsis-h"></i> <span>Topic</span></label>
|
|
43
|
+
<input type="text" id="node-input-topic" class="ff-project-link-input-width">
|
|
44
|
+
</div>
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<script type="text/html" data-template-name="project link out">
|
|
48
|
+
<div class="form-row">
|
|
49
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name">Name</span></label>
|
|
50
|
+
<input type="text" id="node-input-name" class="ff-project-link-input-width">
|
|
51
|
+
</div>
|
|
52
|
+
<div class="form-row">
|
|
53
|
+
<label for="node-input-mode"><i class="fa fa-cog"></i> <span>Mode</span></label>
|
|
54
|
+
<select id="node-input-mode" class="ff-project-link-input-width">
|
|
55
|
+
<option value="link" selected>Send to specified project node</option>
|
|
56
|
+
<option value="return">Return to project link call</option>
|
|
57
|
+
</select>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="form-row ff-project-link-list-row">
|
|
61
|
+
<label><i class="fa fa-sign-out"></i> <span>Target</span></label>
|
|
62
|
+
<span class="ff-project-link-group-option">
|
|
63
|
+
<input type="radio" id="ff-project-link-radio-input-direct" name="ff-project-link-broadcast" value="false" checked />
|
|
64
|
+
<label for="ff-project-link-radio-input-direct">Send message to instance</label>
|
|
65
|
+
</span>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="form-row ff-project-link-list-row">
|
|
68
|
+
<label><span> </span></label>
|
|
69
|
+
<select id="node-input-projectList" class="ff-project-link-input-width" disabled>
|
|
70
|
+
</select>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="form-row ff-project-link-list-row">
|
|
73
|
+
<label><span> </span></label>
|
|
74
|
+
<span class="ff-project-link-group-option">
|
|
75
|
+
<input type="radio" id="ff-project-link-radio-input-broadcast" name="ff-project-link-broadcast" value="true" />
|
|
76
|
+
<label for="ff-project-link-radio-input-broadcast">Broadcast message to all instances</label>
|
|
77
|
+
</span>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="form-row ff-project-link-topic-row">
|
|
80
|
+
<label for="node-input-topic"><i class="fa fa-ellipsis-h"></i> <span>Topic</span></label>
|
|
81
|
+
<input type="text" id="node-input-topic" class="ff-project-link-input-width">
|
|
82
|
+
</div>
|
|
83
|
+
</script>
|
|
84
|
+
<script type="text/html" data-template-name="project link call">
|
|
85
|
+
<div class="form-row">
|
|
86
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name">Name</span></label>
|
|
87
|
+
<input type="text" id="node-input-name" class="ff-project-link-input-width">
|
|
88
|
+
</div>
|
|
89
|
+
<div class="form-row">
|
|
90
|
+
<label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="exec.label.timeout"></span>Timeout</label>
|
|
91
|
+
<input type="text" id="node-input-timeout" placeholder="30" style="width: 80px; margin-right: 5px;">
|
|
92
|
+
<span data-i18n="inject.seconds">sec</span>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="form-row">
|
|
95
|
+
<label for="node-input-projectList"><i class="fa fa-sign-out"></i> <span>Target</span></label>
|
|
96
|
+
<select id="node-input-projectList" class="ff-project-link-input-width">
|
|
97
|
+
</select>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="form-row">
|
|
100
|
+
<label for="node-input-topic"><i class="fa fa-ellipsis-h"></i> <span>Topic</span></label>
|
|
101
|
+
<input type="text" id="node-input-topic" class="ff-project-link-input-width">
|
|
102
|
+
</div>
|
|
103
|
+
</script>
|
|
104
|
+
|
|
105
|
+
<script type="text/javascript">
|
|
106
|
+
/* global RED */
|
|
107
|
+
(function () {
|
|
108
|
+
/**
|
|
109
|
+
* Test a topic string is valid for subscription...
|
|
110
|
+
* * Must not contain the following characters: + # $ \
|
|
111
|
+
* * Must not start with a slash
|
|
112
|
+
* @param {string} subTopic
|
|
113
|
+
* @returns `true` if it is a valid sub topic
|
|
114
|
+
*/
|
|
115
|
+
function isValidSubscriptionTopic (subTopic) {
|
|
116
|
+
return /^(?:(?:[^/$+#\b\f\n\r\t\v\0]+)(?:\/(?:[^/$+#\b\f\n\r\t\v\0]+?))*)$/.test(subTopic)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Test a topic string is valid for publishing...
|
|
121
|
+
* * Must not contain the following characters: + # $ \
|
|
122
|
+
* * Must not start with a slash
|
|
123
|
+
* @param {string} subTopic
|
|
124
|
+
* @returns `true` if it is a valid sub topic
|
|
125
|
+
*/
|
|
126
|
+
function isValidPublishTopic (subTopic) {
|
|
127
|
+
return /^(?:(?:[^/$+#\b\f\n\r\t\v\0]+)(?:\/(?:[^/$+#\b\f\n\r\t\v\0]+?))*)$/.test(subTopic)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function onEditPrepare (node, targetType) {
|
|
131
|
+
let isBroadcast = node.broadcast === true
|
|
132
|
+
let isReturnMode = node.mode === 'return'
|
|
133
|
+
|
|
134
|
+
// Initialise UI state according to node state
|
|
135
|
+
loadProjectList('#node-input-projectList', node.project, targetType || node.type)
|
|
136
|
+
$('#node-input-name').val(node.name)
|
|
137
|
+
$('#node-input-topic').val(node.topic)
|
|
138
|
+
$('#node-input-timeout').val(node.timeout)
|
|
139
|
+
$('#node-input-mode').val(node.mode)
|
|
140
|
+
$('input:radio[name="ff-project-link-broadcast"]').val([isBroadcast.toString()])
|
|
141
|
+
|
|
142
|
+
// watch for switch between broadcast and p2p
|
|
143
|
+
$('input:radio[name="ff-project-link-broadcast"]').on('change', function (e) {
|
|
144
|
+
isBroadcast = e.target.value === 'true'
|
|
145
|
+
updateUI()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
// watch for switch between out and return mode
|
|
149
|
+
if (node.type === 'project link out') {
|
|
150
|
+
$('#node-input-mode').on('change', function (e) {
|
|
151
|
+
isReturnMode = e.target.value === 'return'
|
|
152
|
+
updateUI()
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
updateUI()
|
|
157
|
+
|
|
158
|
+
function updateUI () {
|
|
159
|
+
if (node.type === 'project link out' && isReturnMode) {
|
|
160
|
+
$('.ff-project-link-topic-row').hide()
|
|
161
|
+
$('.ff-project-link-list-row').hide()
|
|
162
|
+
$('#node-input-projectList').prop('disabled', true)
|
|
163
|
+
} else if (node.type === 'project link out') {
|
|
164
|
+
$('.ff-project-link-topic-row').show()
|
|
165
|
+
$('.ff-project-link-list-row').show()
|
|
166
|
+
$('#node-input-projectList').prop('disabled', isBroadcast ? true : null)
|
|
167
|
+
} else if (node.type === 'project link in') {
|
|
168
|
+
$('.ff-project-link-topic-row').show()
|
|
169
|
+
$('.ff-project-link-list-row').show()
|
|
170
|
+
$('#node-input-projectList').prop('disabled', isBroadcast ? null : true)
|
|
171
|
+
} else {
|
|
172
|
+
$('.ff-project-link-topic-row').show()
|
|
173
|
+
$('.ff-project-link-list-row').show()
|
|
174
|
+
$('#node-input-projectList').prop('disabled', null)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function onEditSave (node) {
|
|
180
|
+
node.project = $('#node-input-projectList').val()
|
|
181
|
+
node.name = $('#node-input-name').val()
|
|
182
|
+
node.topic = $('#node-input-topic').val()
|
|
183
|
+
|
|
184
|
+
if (node.type === 'project link call') {
|
|
185
|
+
node.timeout = $('#node-input-timeout').val()
|
|
186
|
+
}
|
|
187
|
+
if (node.type === 'project link out') {
|
|
188
|
+
node.mode = $('#node-input-mode').val()
|
|
189
|
+
}
|
|
190
|
+
if (node.type === 'project link in' || node.type === 'project link out') {
|
|
191
|
+
node.broadcast = $('input:radio[name="ff-project-link-broadcast"]:checked').val() === 'true'
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function loadProjectList (selector, val, nodeType) {
|
|
196
|
+
const el = $(selector)
|
|
197
|
+
if (!el || !el.length) {
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
el.prop('disabled', true)
|
|
201
|
+
val = val || el.val()
|
|
202
|
+
// if ajax call fails, we still want the original value set in the selector
|
|
203
|
+
// so that if the user clicks Done (or the workspace) the same value is
|
|
204
|
+
// re-entered preventing loss or change of original value
|
|
205
|
+
if (val) {
|
|
206
|
+
/** @type {HTMLOptionsCollection} */ const options = el[0].options
|
|
207
|
+
if (!options || !options.length || options.selectedIndex < 0 || options.item(options.selectedIndex).value !== val) {
|
|
208
|
+
options.selectedIndex = -1
|
|
209
|
+
el.append(new Option(val, val, false, true))
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
$.ajax({
|
|
213
|
+
url: 'nr-project-link/projects',
|
|
214
|
+
type: 'GET',
|
|
215
|
+
datatype: 'json'
|
|
216
|
+
})
|
|
217
|
+
.done(function (data) {
|
|
218
|
+
el.empty()
|
|
219
|
+
// broadcast not permitted in link call at this time but has been
|
|
220
|
+
// considered in the code base - possible future iteration
|
|
221
|
+
if (nodeType === 'project link in') {
|
|
222
|
+
el.append(new Option('all instances', 'all', false, val === 'all'))
|
|
223
|
+
}
|
|
224
|
+
const projects = (data.count ? data.projects : null) || []
|
|
225
|
+
for (let index = 0; index < projects.length; index++) {
|
|
226
|
+
const item = projects[index]
|
|
227
|
+
el.append(new Option(item.name, item.id, false, item.id === val))
|
|
228
|
+
}
|
|
229
|
+
$('input:radio[name="ff-project-link-broadcast"]:checked').trigger('change')
|
|
230
|
+
})
|
|
231
|
+
.fail(function (jqXHR, textStatus, errorThrown) {
|
|
232
|
+
$('input:radio[name="ff-project-link-broadcast"]:checked').trigger('change')
|
|
233
|
+
console.error(jqXHR, textStatus, errorThrown)
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function onAdd () {
|
|
238
|
+
if (this.name === '_DEFAULT_') {
|
|
239
|
+
this.name = ''
|
|
240
|
+
RED.actions.invoke('core:generate-node-names', this, { generateHistory: false })
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
RED.nodes.registerType('project link in', {
|
|
245
|
+
category: 'common',
|
|
246
|
+
color: '#87D8CF',
|
|
247
|
+
defaults: {
|
|
248
|
+
name: { value: '_DEFAULT_' },
|
|
249
|
+
project: { value: '', required: true },
|
|
250
|
+
broadcast: { value: false, required: true },
|
|
251
|
+
topic: { value: '', required: true, validate: isValidSubscriptionTopic }
|
|
252
|
+
},
|
|
253
|
+
inputs: 0,
|
|
254
|
+
outputs: 1,
|
|
255
|
+
icon: 'ff-logo.svg',
|
|
256
|
+
paletteLabel: 'project in',
|
|
257
|
+
outputLabels: function (i) {
|
|
258
|
+
return this.name || 'link in'
|
|
259
|
+
},
|
|
260
|
+
// showLabel: false,
|
|
261
|
+
label: function () {
|
|
262
|
+
return this.name || this.topic || 'link in'
|
|
263
|
+
},
|
|
264
|
+
labelStyle: function () {
|
|
265
|
+
return this.name ? 'node_label_italic' : ''
|
|
266
|
+
},
|
|
267
|
+
oneditprepare: function () {
|
|
268
|
+
onEditPrepare(this, 'project link in')
|
|
269
|
+
},
|
|
270
|
+
oneditsave: function () {
|
|
271
|
+
onEditSave(this)
|
|
272
|
+
},
|
|
273
|
+
onadd: onAdd
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
RED.nodes.registerType('project link out', {
|
|
277
|
+
category: 'common',
|
|
278
|
+
color: '#87D8CF',
|
|
279
|
+
defaults: {
|
|
280
|
+
name: { value: '_DEFAULT_' },
|
|
281
|
+
mode: { value: 'link' }, // link || return
|
|
282
|
+
broadcast: { value: false, required: true },
|
|
283
|
+
project: { value: '', required: true },
|
|
284
|
+
topic: {
|
|
285
|
+
value: '',
|
|
286
|
+
validate: function (v) {
|
|
287
|
+
if (this.mode === 'return') {
|
|
288
|
+
return true
|
|
289
|
+
}
|
|
290
|
+
return v && isValidPublishTopic(v)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
align: 'right',
|
|
295
|
+
inputs: 1,
|
|
296
|
+
outputs: 0,
|
|
297
|
+
icon: function () {
|
|
298
|
+
if (this.mode === 'return') {
|
|
299
|
+
return 'ff-logo.svg'
|
|
300
|
+
} else {
|
|
301
|
+
return 'ff-logo.svg'
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
paletteLabel: 'project out',
|
|
305
|
+
inputLabels: function (i) {
|
|
306
|
+
return this.name || (this.mode === 'return' ? 'link return' : 'link out')
|
|
307
|
+
},
|
|
308
|
+
// showLabel: false,
|
|
309
|
+
label: function () {
|
|
310
|
+
return this.name || (this.mode === 'return' ? 'link return' : this.topic) || 'link out'
|
|
311
|
+
},
|
|
312
|
+
labelStyle: function () {
|
|
313
|
+
return this.name ? 'node_label_italic' : ''
|
|
314
|
+
},
|
|
315
|
+
oneditprepare: function () {
|
|
316
|
+
onEditPrepare(this, 'project link out')
|
|
317
|
+
$('#node-input-mode').on('change', function () {
|
|
318
|
+
$('.node-input-link-rows').toggle(this.value === 'link')
|
|
319
|
+
})
|
|
320
|
+
if (!this.mode) {
|
|
321
|
+
$('#node-input-mode').val('link').trigger('change')
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
oneditsave: function () {
|
|
325
|
+
onEditSave(this)
|
|
326
|
+
},
|
|
327
|
+
onadd: onAdd
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
RED.nodes.registerType('project link call', {
|
|
331
|
+
category: 'common',
|
|
332
|
+
color: '#87D8CF',
|
|
333
|
+
defaults: {
|
|
334
|
+
name: { value: '' },
|
|
335
|
+
project: { value: '', required: true },
|
|
336
|
+
topic: { value: '', required: true, validate: isValidPublishTopic },
|
|
337
|
+
timeout: {
|
|
338
|
+
value: '30',
|
|
339
|
+
label: RED._('node-red:link.timeout'),
|
|
340
|
+
validate: RED.validators.number(true)
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
inputs: 1,
|
|
344
|
+
outputs: 1,
|
|
345
|
+
icon: 'ff-logo.svg',
|
|
346
|
+
paletteLabel: 'project call',
|
|
347
|
+
inputLabels: function (i) {
|
|
348
|
+
return this.name || 'link call'
|
|
349
|
+
},
|
|
350
|
+
label: function () {
|
|
351
|
+
return this.name || this.topic || 'link call'
|
|
352
|
+
},
|
|
353
|
+
labelStyle: function () {
|
|
354
|
+
return this.name ? 'node_label_italic' : ''
|
|
355
|
+
},
|
|
356
|
+
oneditprepare: function () {
|
|
357
|
+
onEditPrepare(this, 'project link call')
|
|
358
|
+
},
|
|
359
|
+
oneditsave: function () {
|
|
360
|
+
onEditSave(this)
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
})()
|
|
364
|
+
</script>
|
|
365
|
+
|
|
366
|
+
<script type="text/html" data-help-name="project link in">
|
|
367
|
+
<p>Receive messages from other Node-RED instances within your FlowFuse Team</p>
|
|
368
|
+
<h3>Details</h3>
|
|
369
|
+
<p>This node can either listen for messages broadcast by other instances,
|
|
370
|
+
or listen for messages sent directly to this instance.</p>
|
|
371
|
+
<p>The node is configured with a <code>topic</code> to listen on. This works
|
|
372
|
+
like an MQTT topic - allowing projects to send messages targeting different
|
|
373
|
+
subscribers.</p>
|
|
374
|
+
<p>The node does not support MQTT wildcard characters - a fully qualified topic
|
|
375
|
+
must be used.</p>
|
|
376
|
+
<h3>Output</h3>
|
|
377
|
+
<dl class="message-properties">
|
|
378
|
+
<dt><i>msg</i> <span class="property-type">object</span></dt>
|
|
379
|
+
<dd>
|
|
380
|
+
The message sent by another Node-RED instance to this node.
|
|
381
|
+
</dd>
|
|
382
|
+
<dt><i>projectLink</i> <span class="property-type">object</span></dt>
|
|
383
|
+
<dd>
|
|
384
|
+
This property contains information about the source of the message.
|
|
385
|
+
<ul>
|
|
386
|
+
<li><code>instanceId</code> - the id of the instance that sent the message</li>
|
|
387
|
+
<li><code>projectId</code> - <i>deprecated</i>: the id of the instance that sent the message</li>
|
|
388
|
+
<li><code>deviceId</code> - if present, the id of the device that sent the message</li>
|
|
389
|
+
<li><code>deviceName</code> - if present, the name of the device that sent the message</li>
|
|
390
|
+
<li><code>deviceType</code> - if present, the type of the device that sent the message</li>
|
|
391
|
+
<li><code>topic</code> - the topic the message was received on</li>
|
|
392
|
+
<li><code>callStack</code> - when using the Project Call node, this contains
|
|
393
|
+
information about the call stack. This property must not be modified.</li>
|
|
394
|
+
</ul>
|
|
395
|
+
</dd>
|
|
396
|
+
</dl>
|
|
397
|
+
</script>
|
|
398
|
+
|
|
399
|
+
<script type="text/html" data-help-name="project link out">
|
|
400
|
+
<p>Send messages to other projects within your FlowForge Team</p>
|
|
401
|
+
<h3>Details</h3>
|
|
402
|
+
<p>This node can be used to send messages to other Node-RED instances.</p>
|
|
403
|
+
<p>
|
|
404
|
+
It provides three modes of operation:
|
|
405
|
+
<ul>
|
|
406
|
+
<li>send messages to another instance</li>
|
|
407
|
+
<li>broadcast messages to any instance listening on the same topic</li>
|
|
408
|
+
<li>return the message to its sender if it originated from a Project Call node</li>
|
|
409
|
+
</ul>
|
|
410
|
+
</p>
|
|
411
|
+
<p>
|
|
412
|
+
When configured to send or broadcast messages to other instances, the node
|
|
413
|
+
is configured with a <code>topic</code> to send on. This works
|
|
414
|
+
like an MQTT topic - allowing instances to send messages targeting different
|
|
415
|
+
subscribers.
|
|
416
|
+
</p>
|
|
417
|
+
<p>
|
|
418
|
+
When configured to return the message to the previous Project Call node,
|
|
419
|
+
the node requires the property <code>msg.projectLink.callStack</code> to
|
|
420
|
+
be present. This property is set by the Project In node when it receives
|
|
421
|
+
messages from a Project Call node. If this property is not present, the
|
|
422
|
+
node will be unable to respond properly.
|
|
423
|
+
</p>
|
|
424
|
+
<h3>Input</h3>
|
|
425
|
+
<dl class="message-properties">
|
|
426
|
+
<dt><i>msg</i> <span class="property-type">object</span></dt>
|
|
427
|
+
<dd>
|
|
428
|
+
<p>The node will send the complete message object it receives.</p>\
|
|
429
|
+
<p>Due to the way messages are sent, not all types of property will
|
|
430
|
+
be included. For example, the <code>msg.req</code> and <code>msg.res</code> properties
|
|
431
|
+
used by the HTTP nodes will not be sent.
|
|
432
|
+
</p>
|
|
433
|
+
</dd>
|
|
434
|
+
</dl>
|
|
435
|
+
</script>
|
|
436
|
+
|
|
437
|
+
<script type="text/html" data-help-name="project link call">
|
|
438
|
+
<p>Send messages to other Node-RED instances within your FlowForge Team and get a response back</p>
|
|
439
|
+
<h3>Details</h3>
|
|
440
|
+
<p>
|
|
441
|
+
This node can be used to send messages to other instances and then wait
|
|
442
|
+
for a response to be sent back.
|
|
443
|
+
</p>
|
|
444
|
+
<p>
|
|
445
|
+
The node can be configured with a <code>timeout</code> for how long it
|
|
446
|
+
should wait for a response. If a response does not arrive, it will log
|
|
447
|
+
an error that can be caught with a Catch node
|
|
448
|
+
</p>
|
|
449
|
+
<p>
|
|
450
|
+
The node is configured with a <code>topic</code> to send on. This works
|
|
451
|
+
like an MQTT topic - allowing instances to send messages targeting different
|
|
452
|
+
subscribers.
|
|
453
|
+
</p>
|
|
454
|
+
<h3>Output</h3>
|
|
455
|
+
<dl class="message-properties">
|
|
456
|
+
<dt><i>msg</i> <span class="property-type">object</span></dt>
|
|
457
|
+
<dd>
|
|
458
|
+
The message sent by another instance to this node.
|
|
459
|
+
</dd>
|
|
460
|
+
<dt><i>projectLink</i> <span class="property-type">object</span></dt>
|
|
461
|
+
<dd>
|
|
462
|
+
This property contains information about the source of the message.
|
|
463
|
+
<ul>
|
|
464
|
+
<li><code>instanceId</code> - the id of the instance that sent the message</li>
|
|
465
|
+
<li><code>projectId</code> - <i>deprecated</i>: the id of the instance that sent the message</li>
|
|
466
|
+
<li><code>deviceId</code> - if present, the id of the device that sent the message</li>
|
|
467
|
+
<li><code>deviceName</code> - if present, the name of the device that sent the message</li>
|
|
468
|
+
<li><code>deviceType</code> - if present, the type of the device that sent the message</li>
|
|
469
|
+
<li><code>topic</code> - the topic the message was received on</li>
|
|
470
|
+
<li><code>callStack</code> - when using the Project Call node, this contains
|
|
471
|
+
information about the call stack. This property must not be modified.</li>
|
|
472
|
+
</ul>
|
|
473
|
+
</dd>
|
|
474
|
+
</dl>
|
|
475
|
+
</script>
|