node-red-contrib-3dm-space 1.0.0 → 1.0.3
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/3dm-cloud-config.html +270 -83
- package/3dm-cloud-config.js +826 -123
- package/3dm-config-store.html +236 -0
- package/3dm-config-store.js +883 -0
- package/README.md +217 -31
- package/package.json +8 -5
package/3dm-cloud-config.html
CHANGED
|
@@ -1,108 +1,295 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
(function () {
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
function clampOutputs(value) {
|
|
6
|
+
var n = parseInt(value, 10);
|
|
7
|
+
|
|
8
|
+
if (isNaN(n)) {
|
|
9
|
+
n = 24;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return Math.max(1, Math.min(n, 24));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function populateConfigOutputOptions(maxOutputs, currentValue) {
|
|
16
|
+
var select = $("#node-input-configOutput");
|
|
17
|
+
var current = parseInt(currentValue, 10);
|
|
18
|
+
|
|
19
|
+
if (isNaN(current)) {
|
|
20
|
+
current = 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
select.empty();
|
|
24
|
+
select.append(
|
|
25
|
+
$("<option></option>")
|
|
26
|
+
.attr("value", "0")
|
|
27
|
+
.text("Disabled")
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
for (var i = 1; i <= maxOutputs; i += 1) {
|
|
31
|
+
select.append(
|
|
32
|
+
$("<option></option>")
|
|
33
|
+
.attr("value", String(i))
|
|
34
|
+
.text("Output " + i)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (current > maxOutputs) {
|
|
39
|
+
current = 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
select.val(String(current));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
RED.nodes.registerType("3dm-config-store", {
|
|
46
|
+
category: "3DM.space",
|
|
47
|
+
color: "#6D6D6D",
|
|
4
48
|
defaults: {
|
|
5
49
|
name: { value: "" },
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
50
|
+
configName: { value: "" },
|
|
51
|
+
outputs: {
|
|
52
|
+
value: 24,
|
|
53
|
+
validate: function (v) {
|
|
54
|
+
var n = Number(v);
|
|
55
|
+
return !isNaN(n) && n >= 1 && n <= 24;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
tickSeconds: {
|
|
59
|
+
value: 20,
|
|
60
|
+
validate: function (v) {
|
|
61
|
+
var n = Number(v);
|
|
62
|
+
return !isNaN(n) && n >= 1 && n <= 60;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
outputMode: { value: "change" },
|
|
66
|
+
configOutput: { value: 0 },
|
|
67
|
+
emitConfigOnUpdate: { value: false }
|
|
11
68
|
},
|
|
69
|
+
inputs: 1,
|
|
70
|
+
outputs: 24,
|
|
71
|
+
icon: "font-awesome/fa-database",
|
|
12
72
|
label: function () {
|
|
13
|
-
return this.name ||
|
|
73
|
+
return this.name || "3DM config store";
|
|
74
|
+
},
|
|
75
|
+
paletteLabel: "3DM config store",
|
|
76
|
+
outputLabels: function (index) {
|
|
77
|
+
return "Output " + (index + 1);
|
|
78
|
+
},
|
|
79
|
+
oneditprepare: function () {
|
|
80
|
+
var outputCount = clampOutputs(this.outputs || 24);
|
|
81
|
+
|
|
82
|
+
$("#node-input-outputs").val(outputCount);
|
|
83
|
+
populateConfigOutputOptions(outputCount, this.configOutput || 0);
|
|
84
|
+
|
|
85
|
+
$("#node-input-outputs").on("input change", function () {
|
|
86
|
+
var count = clampOutputs($(this).val());
|
|
87
|
+
populateConfigOutputOptions(count, $("#node-input-configOutput").val());
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
oneditsave: function () {
|
|
91
|
+
var outputCount = clampOutputs($("#node-input-outputs").val());
|
|
92
|
+
var configOutput = parseInt($("#node-input-configOutput").val(), 10);
|
|
93
|
+
|
|
94
|
+
this.outputs = outputCount;
|
|
95
|
+
|
|
96
|
+
if (isNaN(configOutput) || configOutput > outputCount) {
|
|
97
|
+
this.configOutput = 0;
|
|
98
|
+
$("#node-input-configOutput").val("0");
|
|
99
|
+
}
|
|
14
100
|
}
|
|
15
101
|
});
|
|
102
|
+
})();
|
|
16
103
|
</script>
|
|
17
104
|
|
|
18
|
-
<script type="text/html" data-template-name="3dm-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.three-dm-login-row {
|
|
28
|
-
background: #3a4152;
|
|
29
|
-
border-radius: 8px;
|
|
30
|
-
padding: 10px 12px;
|
|
31
|
-
margin-bottom: 12px;
|
|
32
|
-
}
|
|
105
|
+
<script type="text/html" data-template-name="3dm-config-store">
|
|
106
|
+
<div class="form-row">
|
|
107
|
+
<label for="node-input-name">
|
|
108
|
+
<i class="fa fa-tag"></i> Node Name
|
|
109
|
+
</label>
|
|
110
|
+
<input type="text" id="node-input-name" placeholder="Optional, e.g. Pump Config Store">
|
|
111
|
+
</div>
|
|
33
112
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
113
|
+
<div class="form-row">
|
|
114
|
+
<label for="node-input-configName">
|
|
115
|
+
<i class="fa fa-folder-open"></i> Config Name
|
|
116
|
+
</label>
|
|
117
|
+
<input type="text" id="node-input-configName" placeholder="Optional, e.g. mainScheduler">
|
|
118
|
+
</div>
|
|
41
119
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
padding: 4px 0;
|
|
50
|
-
}
|
|
120
|
+
<div class="form-row">
|
|
121
|
+
<label for="node-input-outputs">
|
|
122
|
+
<i class="fa fa-random"></i> Active Outputs
|
|
123
|
+
</label>
|
|
124
|
+
<input type="number" id="node-input-outputs" min="1" max="24" placeholder="24" style="width:100px;">
|
|
125
|
+
<span> outputs</span>
|
|
126
|
+
</div>
|
|
51
127
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
128
|
+
<div class="form-row">
|
|
129
|
+
<label for="node-input-tickSeconds">
|
|
130
|
+
<i class="fa fa-clock-o"></i> Check Every
|
|
131
|
+
</label>
|
|
132
|
+
<input type="number" id="node-input-tickSeconds" min="1" max="60" placeholder="20" style="width:100px;">
|
|
133
|
+
<span> seconds</span>
|
|
134
|
+
</div>
|
|
55
135
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
136
|
+
<div class="form-row">
|
|
137
|
+
<label for="node-input-outputMode">
|
|
138
|
+
<i class="fa fa-sign-out"></i> Output Mode
|
|
139
|
+
</label>
|
|
140
|
+
<select id="node-input-outputMode" style="width:70%;">
|
|
141
|
+
<option value="change">Only when output changes</option>
|
|
142
|
+
<option value="always">Every check</option>
|
|
143
|
+
</select>
|
|
144
|
+
</div>
|
|
60
145
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</style>
|
|
67
|
-
|
|
68
|
-
<div class="three-dm-login-panel">
|
|
69
|
-
<div class="three-dm-login-row">
|
|
70
|
-
<label for="node-config-input-clientid">Client ID</label>
|
|
71
|
-
<input type="text" id="node-config-input-clientid" placeholder="Paste Client ID from 3DM.space">
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<div class="three-dm-login-row">
|
|
75
|
-
<label for="node-config-input-username">User Name*</label>
|
|
76
|
-
<input type="text" id="node-config-input-username" placeholder="Paste User Name from 3DM.space">
|
|
77
|
-
</div>
|
|
78
|
-
|
|
79
|
-
<div class="three-dm-login-row">
|
|
80
|
-
<label for="node-config-input-password">Password</label>
|
|
81
|
-
<input type="password" id="node-config-input-password" placeholder="Paste Password from 3DM.space">
|
|
82
|
-
</div>
|
|
146
|
+
<div class="form-row">
|
|
147
|
+
<label for="node-input-configOutput">
|
|
148
|
+
<i class="fa fa-share-square-o"></i> Config Output
|
|
149
|
+
</label>
|
|
150
|
+
<select id="node-input-configOutput" style="width:70%;"></select>
|
|
83
151
|
</div>
|
|
84
152
|
|
|
85
153
|
<div class="form-row">
|
|
86
|
-
<label for="node-
|
|
87
|
-
<i class="fa fa-
|
|
154
|
+
<label for="node-input-emitConfigOnUpdate">
|
|
155
|
+
<i class="fa fa-refresh"></i> Send Config
|
|
88
156
|
</label>
|
|
89
|
-
<input type="
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
157
|
+
<input type="checkbox" id="node-input-emitConfigOnUpdate" style="display:inline-block; width:auto; vertical-align:top;">
|
|
158
|
+
<span> send stored config when updated</span>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div class="form-tips">
|
|
162
|
+
<b>Tip:</b> Leave Config Name blank to allow this node to store and use all config blocks sent under <code>configStore</code>.
|
|
93
163
|
</div>
|
|
94
164
|
</script>
|
|
95
165
|
|
|
96
|
-
<script type="text/html" data-help-name="3dm-
|
|
97
|
-
<p>
|
|
166
|
+
<script type="text/html" data-help-name="3dm-config-store">
|
|
167
|
+
<p>
|
|
168
|
+
Stores configuration sent from 3DM.space and runs local schedule/control logic.
|
|
169
|
+
</p>
|
|
170
|
+
|
|
171
|
+
<p>
|
|
172
|
+
This node is normally placed after a <b>3DM In</b> node.
|
|
173
|
+
</p>
|
|
174
|
+
|
|
175
|
+
<pre>3DM In → 3DM Config Store → active outputs</pre>
|
|
176
|
+
|
|
177
|
+
<h3>Config Store Format</h3>
|
|
178
|
+
|
|
179
|
+
<p>
|
|
180
|
+
Incoming messages should contain a main <code>configStore</code> object.
|
|
181
|
+
Each config block inside it should have its own name.
|
|
182
|
+
</p>
|
|
183
|
+
|
|
184
|
+
<pre>{
|
|
185
|
+
"configStore": {
|
|
186
|
+
"mainScheduler": {
|
|
187
|
+
"type": "scheduler",
|
|
188
|
+
"data": []
|
|
189
|
+
},
|
|
190
|
+
"pumpSetpoints": {
|
|
191
|
+
"type": "setpoints",
|
|
192
|
+
"data": {
|
|
193
|
+
"startLevel": 30,
|
|
194
|
+
"stopLevel": 80
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}</pre>
|
|
199
|
+
|
|
200
|
+
<h3>Scheduler Config</h3>
|
|
201
|
+
|
|
202
|
+
<p>
|
|
203
|
+
Scheduler blocks use <code>type: "scheduler"</code>.
|
|
204
|
+
</p>
|
|
205
|
+
|
|
206
|
+
<pre>{
|
|
207
|
+
"configStore": {
|
|
208
|
+
"mainScheduler": {
|
|
209
|
+
"type": "scheduler",
|
|
210
|
+
"data": [
|
|
211
|
+
{
|
|
212
|
+
"name": "Pump 1 Morning Run",
|
|
213
|
+
"output": "output1",
|
|
214
|
+
"controlType": "schedule",
|
|
215
|
+
"mode": "Auto Schedule",
|
|
216
|
+
"days": ["mon", "tue", "wed", "thu", "fri"],
|
|
217
|
+
"startHour": 6,
|
|
218
|
+
"startMinute": 0,
|
|
219
|
+
"runHour": 1,
|
|
220
|
+
"runMinute": 30
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}</pre>
|
|
226
|
+
|
|
227
|
+
<h3>Control Config</h3>
|
|
228
|
+
|
|
229
|
+
<p>
|
|
230
|
+
Control entries can use live input values and stored setpoints.
|
|
231
|
+
</p>
|
|
232
|
+
|
|
233
|
+
<pre>{
|
|
234
|
+
"name": "Tank Level Control",
|
|
235
|
+
"output": "output1",
|
|
236
|
+
"controlType": "control",
|
|
237
|
+
"mode": "AUTO",
|
|
238
|
+
"variable": "tank_level",
|
|
239
|
+
"lowSetpointKey": "pumpSetpoints.data.startLevel",
|
|
240
|
+
"highSetpointKey": "pumpSetpoints.data.stopLevel",
|
|
241
|
+
"direction": "in"
|
|
242
|
+
}</pre>
|
|
243
|
+
|
|
244
|
+
<h3>Config Name</h3>
|
|
245
|
+
|
|
246
|
+
<p>
|
|
247
|
+
Leave <b>Config Name</b> blank to allow all config blocks.
|
|
248
|
+
</p>
|
|
249
|
+
|
|
250
|
+
<p>
|
|
251
|
+
Enter a name such as <code>mainScheduler</code> if this node should only use one config block.
|
|
252
|
+
</p>
|
|
253
|
+
|
|
254
|
+
<h3>Outputs</h3>
|
|
255
|
+
|
|
256
|
+
<p>
|
|
257
|
+
The node can be set from 1 to 24 active outputs.
|
|
258
|
+
</p>
|
|
259
|
+
|
|
260
|
+
<p>
|
|
261
|
+
Scheduler and control items use output names such as:
|
|
262
|
+
</p>
|
|
263
|
+
|
|
264
|
+
<pre>output1
|
|
265
|
+
output2
|
|
266
|
+
output3</pre>
|
|
267
|
+
|
|
268
|
+
<p>
|
|
269
|
+
If an item uses an output higher than the active output count, that item is skipped.
|
|
270
|
+
</p>
|
|
271
|
+
|
|
272
|
+
<p>
|
|
273
|
+
If multiple schedule/control entries use the same output, they are combined using OR logic.
|
|
274
|
+
If any entry wants the output ON, the final output is ON.
|
|
275
|
+
</p>
|
|
276
|
+
|
|
277
|
+
<h3>Local Storage</h3>
|
|
278
|
+
|
|
279
|
+
<p>
|
|
280
|
+
Config is saved locally on the gateway. If Node-RED restarts, the last saved config is loaded again.
|
|
281
|
+
</p>
|
|
282
|
+
|
|
283
|
+
<h3>Output Mode</h3>
|
|
98
284
|
|
|
99
|
-
<
|
|
285
|
+
<ul>
|
|
286
|
+
<li><b>Only when output changes</b>: sends an output only when the final state changes.</li>
|
|
287
|
+
<li><b>Every check</b>: sends outputs every check cycle.</li>
|
|
288
|
+
</ul>
|
|
100
289
|
|
|
101
|
-
<
|
|
102
|
-
<li>Client ID</li>
|
|
103
|
-
<li>User Name*</li>
|
|
104
|
-
<li>Password</li>
|
|
105
|
-
</ol>
|
|
290
|
+
<h3>Config Output</h3>
|
|
106
291
|
|
|
107
|
-
<p>
|
|
292
|
+
<p>
|
|
293
|
+
Optional. Select an active output if you want the full stored config sent out as a message.
|
|
294
|
+
</p>
|
|
108
295
|
</script>
|