@bldgblocks/node-red-contrib-control 0.1.34 → 0.1.36

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.
Files changed (110) hide show
  1. package/nodes/accumulate-block.html +18 -8
  2. package/nodes/accumulate-block.js +39 -44
  3. package/nodes/add-block.html +1 -1
  4. package/nodes/add-block.js +18 -11
  5. package/nodes/alarm-collector.html +260 -0
  6. package/nodes/alarm-collector.js +292 -0
  7. package/nodes/alarm-config.html +129 -0
  8. package/nodes/alarm-config.js +126 -0
  9. package/nodes/alarm-service.html +96 -0
  10. package/nodes/alarm-service.js +142 -0
  11. package/nodes/analog-switch-block.js +25 -36
  12. package/nodes/and-block.js +44 -15
  13. package/nodes/average-block.js +46 -41
  14. package/nodes/boolean-switch-block.js +10 -28
  15. package/nodes/boolean-to-number-block.html +18 -5
  16. package/nodes/boolean-to-number-block.js +24 -16
  17. package/nodes/cache-block.js +24 -37
  18. package/nodes/call-status-block.html +91 -32
  19. package/nodes/call-status-block.js +398 -115
  20. package/nodes/changeover-block.html +5 -0
  21. package/nodes/changeover-block.js +167 -162
  22. package/nodes/comment-block.html +1 -1
  23. package/nodes/comment-block.js +14 -9
  24. package/nodes/compare-block.html +14 -4
  25. package/nodes/compare-block.js +23 -18
  26. package/nodes/contextual-label-block.html +5 -0
  27. package/nodes/contextual-label-block.js +6 -16
  28. package/nodes/convert-block.html +25 -39
  29. package/nodes/convert-block.js +31 -16
  30. package/nodes/count-block.html +11 -5
  31. package/nodes/count-block.js +34 -32
  32. package/nodes/delay-block.js +58 -53
  33. package/nodes/divide-block.js +43 -45
  34. package/nodes/edge-block.html +17 -10
  35. package/nodes/edge-block.js +43 -41
  36. package/nodes/enum-switch-block.js +6 -6
  37. package/nodes/frequency-block.html +6 -1
  38. package/nodes/frequency-block.js +64 -74
  39. package/nodes/global-getter.html +51 -15
  40. package/nodes/global-getter.js +43 -13
  41. package/nodes/global-setter.html +1 -1
  42. package/nodes/global-setter.js +40 -12
  43. package/nodes/history-buffer.html +96 -0
  44. package/nodes/history-buffer.js +461 -0
  45. package/nodes/history-collector.html +29 -1
  46. package/nodes/history-collector.js +37 -16
  47. package/nodes/history-config.html +13 -1
  48. package/nodes/history-service.html +84 -0
  49. package/nodes/history-service.js +52 -0
  50. package/nodes/hysteresis-block.html +5 -0
  51. package/nodes/hysteresis-block.js +13 -16
  52. package/nodes/interpolate-block.html +20 -2
  53. package/nodes/interpolate-block.js +39 -50
  54. package/nodes/join.html +78 -0
  55. package/nodes/join.js +78 -0
  56. package/nodes/latch-block.js +12 -14
  57. package/nodes/load-sequence-block.js +102 -110
  58. package/nodes/max-block.js +26 -26
  59. package/nodes/memory-block.js +57 -58
  60. package/nodes/min-block.js +26 -25
  61. package/nodes/minmax-block.js +35 -34
  62. package/nodes/modulo-block.js +45 -43
  63. package/nodes/multiply-block.js +43 -41
  64. package/nodes/negate-block.html +17 -7
  65. package/nodes/negate-block.js +25 -19
  66. package/nodes/network-point-read.html +128 -0
  67. package/nodes/network-point-read.js +230 -0
  68. package/nodes/{network-register.html → network-point-register.html} +94 -7
  69. package/nodes/{network-register.js → network-point-register.js} +18 -4
  70. package/nodes/network-point-write.html +149 -0
  71. package/nodes/network-point-write.js +222 -0
  72. package/nodes/network-service-bridge.html +131 -0
  73. package/nodes/network-service-bridge.js +376 -0
  74. package/nodes/network-service-read.html +81 -0
  75. package/nodes/{network-read.js → network-service-read.js} +4 -3
  76. package/nodes/{network-point-registry.html → network-service-registry.html} +19 -4
  77. package/nodes/{network-point-registry.js → network-service-registry.js} +7 -2
  78. package/nodes/network-service-write.html +89 -0
  79. package/nodes/{network-write.js → network-service-write.js} +3 -3
  80. package/nodes/nullify-block.js +13 -15
  81. package/nodes/on-change-block.html +17 -9
  82. package/nodes/on-change-block.js +49 -46
  83. package/nodes/oneshot-block.html +13 -10
  84. package/nodes/oneshot-block.js +57 -75
  85. package/nodes/or-block.js +44 -15
  86. package/nodes/pid-block.html +54 -4
  87. package/nodes/pid-block.js +459 -248
  88. package/nodes/priority-block.js +24 -35
  89. package/nodes/rate-limit-block.js +70 -72
  90. package/nodes/rate-of-change-block.html +33 -14
  91. package/nodes/rate-of-change-block.js +74 -62
  92. package/nodes/round-block.html +14 -9
  93. package/nodes/round-block.js +32 -25
  94. package/nodes/saw-tooth-wave-block.js +49 -76
  95. package/nodes/scale-range-block.html +12 -6
  96. package/nodes/scale-range-block.js +46 -39
  97. package/nodes/sine-wave-block.js +49 -57
  98. package/nodes/string-builder-block.js +6 -6
  99. package/nodes/subtract-block.js +38 -34
  100. package/nodes/thermistor-block.js +44 -44
  101. package/nodes/tick-tock-block.js +32 -32
  102. package/nodes/time-sequence-block.js +30 -42
  103. package/nodes/triangle-wave-block.js +49 -69
  104. package/nodes/tstat-block.js +34 -44
  105. package/nodes/units-block.html +90 -69
  106. package/nodes/units-block.js +22 -30
  107. package/nodes/utils.js +206 -3
  108. package/package.json +14 -6
  109. package/nodes/network-read.html +0 -56
  110. package/nodes/network-write.html +0 -65
@@ -1,43 +1,43 @@
1
1
  module.exports = function(RED) {
2
+ const utils = require('./utils')(RED);
2
3
  function LoadSequenceBlockNode(config) {
3
4
  RED.nodes.createNode(this, config);
4
5
  const node = this;
5
6
 
6
7
  // Initialize runtime state
7
- node.runtime = {
8
- name: config.name || "",
9
- enable: config.enable,
10
- hysteresis: parseFloat(config.hysteresis),
11
- threshold1: parseFloat(config.threshold1),
12
- threshold2: parseFloat(config.threshold2),
13
- threshold3: parseFloat(config.threshold3),
14
- threshold4: parseFloat(config.threshold4),
15
- feedback1: config.feedback1,
16
- feedback2: config.feedback2,
17
- feedback3: config.feedback3,
18
- feedback4: config.feedback4,
19
- out1: false,
20
- out2: false,
21
- out3: false,
22
- out4: false,
23
- dOn: 0,
24
- lastInput: 0,
25
- lastOutputs: [false, false, false, false]
26
- };
8
+ // Initialize state
9
+ node.name = config.name || "";
10
+ node.enable = config.enable;
11
+ node.hysteresis = parseFloat(config.hysteresis);
12
+ node.threshold1 = parseFloat(config.threshold1);
13
+ node.threshold2 = parseFloat(config.threshold2);
14
+ node.threshold3 = parseFloat(config.threshold3);
15
+ node.threshold4 = parseFloat(config.threshold4);
16
+ node.feedback1 = config.feedback1;
17
+ node.feedback2 = config.feedback2;
18
+ node.feedback3 = config.feedback3;
19
+ node.feedback4 = config.feedback4;
20
+ node.out1 = false;
21
+ node.out2 = false;
22
+ node.out3 = false;
23
+ node.out4 = false;
24
+ node.dOn = 0;
25
+ node.lastInput = 0;
26
+ node.lastOutputs = [false, false, false, false];
27
27
 
28
28
  // Validate initial config
29
- if (isNaN(node.runtime.hysteresis) || node.runtime.hysteresis < 0) {
30
- node.runtime.hysteresis = 0.5;
31
- node.status({ fill: "red", shape: "ring", text: "invalid hysteresis" });
29
+ if (isNaN(node.hysteresis) || node.hysteresis < 0) {
30
+ node.hysteresis = 0.5;
31
+ utils.setStatusError(node, "invalid hysteresis");
32
32
  }
33
- if (isNaN(node.runtime.threshold1) || isNaN(node.runtime.threshold2) || isNaN(node.runtime.threshold3) || isNaN(node.runtime.threshold4) ||
34
- node.runtime.threshold1 < 0 || node.runtime.threshold2 < 0 || node.runtime.threshold3 < 0 || node.runtime.threshold4 < 0 ||
35
- node.runtime.threshold1 >= node.runtime.threshold2 || node.runtime.threshold2 >= node.runtime.threshold3 || node.runtime.threshold3 >= node.runtime.threshold4) {
36
- node.runtime.threshold1 = 10.0;
37
- node.runtime.threshold2 = 20.0;
38
- node.runtime.threshold3 = 30.0;
39
- node.runtime.threshold4 = 40.0;
40
- node.status({ fill: "red", shape: "ring", text: "invalid threshold order" });
33
+ if (isNaN(node.threshold1) || isNaN(node.threshold2) || isNaN(node.threshold3) || isNaN(node.threshold4) ||
34
+ node.threshold1 < 0 || node.threshold2 < 0 || node.threshold3 < 0 || node.threshold4 < 0 ||
35
+ node.threshold1 >= node.threshold2 || node.threshold2 >= node.threshold3 || node.threshold3 >= node.threshold4) {
36
+ node.threshold1 = 10.0;
37
+ node.threshold2 = 20.0;
38
+ node.threshold3 = 30.0;
39
+ node.threshold4 = 40.0;
40
+ utils.setStatusError(node, "invalid threshold order");
41
41
  }
42
42
 
43
43
  node.on("input", function(msg, send, done) {
@@ -45,7 +45,7 @@ module.exports = function(RED) {
45
45
 
46
46
  // Guard against invalid message
47
47
  if (!msg) {
48
- node.status({ fill: "red", shape: "ring", text: "invalid message" });
48
+ utils.setStatusError(node, "invalid message");
49
49
  if (done) done();
50
50
  return;
51
51
  }
@@ -53,29 +53,29 @@ module.exports = function(RED) {
53
53
  // Handle configuration updates
54
54
  if (msg.hasOwnProperty("context")) {
55
55
  if (!msg.hasOwnProperty("payload")) {
56
- node.status({ fill: "red", shape: "ring", text: `missing payload for ${msg.context}` });
56
+ utils.setStatusError(node, `missing payload for ${msg.context}`);
57
57
  if (done) done();
58
58
  return;
59
59
  }
60
60
  switch (msg.context) {
61
61
  case "enable":
62
62
  if (typeof msg.payload !== "boolean") {
63
- node.status({ fill: "red", shape: "ring", text: "invalid enable" });
63
+ utils.setStatusError(node, "invalid enable");
64
64
  if (done) done();
65
65
  return;
66
66
  }
67
- node.runtime.enable = msg.payload;
68
- node.status({ fill: "green", shape: "dot", text: `enable: ${node.runtime.enable}` });
67
+ node.enable = msg.payload;
68
+ utils.setStatusOK(node, `enable: ${node.enable}`);
69
69
  break;
70
70
  case "hysteresis":
71
71
  const hystValue = parseFloat(msg.payload);
72
72
  if (isNaN(hystValue) || hystValue < 0) {
73
- node.status({ fill: "red", shape: "ring", text: "invalid hysteresis" });
73
+ utils.setStatusError(node, "invalid hysteresis");
74
74
  if (done) done();
75
75
  return;
76
76
  }
77
- node.runtime.hysteresis = hystValue;
78
- node.status({ fill: "green", shape: "dot", text: `hysteresis: ${node.runtime.hysteresis}` });
77
+ node.hysteresis = hystValue;
78
+ utils.setStatusOK(node, `hysteresis: ${node.hysteresis}`);
79
79
  break;
80
80
  case "threshold1":
81
81
  case "threshold2":
@@ -83,36 +83,36 @@ module.exports = function(RED) {
83
83
  case "threshold4":
84
84
  const threshValue = parseFloat(msg.payload);
85
85
  if (isNaN(threshValue) || threshValue < 0) {
86
- node.status({ fill: "red", shape: "ring", text: `invalid ${msg.context}` });
86
+ utils.setStatusError(node, `invalid ${msg.context}`);
87
87
  if (done) done();
88
88
  return;
89
89
  }
90
- const prevThresholds = [node.runtime.threshold1, node.runtime.threshold2, node.runtime.threshold3, node.runtime.threshold4];
90
+ const prevThresholds = [node.threshold1, node.threshold2, node.threshold3, node.threshold4];
91
91
  const index = parseInt(msg.context.replace("threshold", "")) - 1;
92
92
  const newThresholds = [...prevThresholds];
93
93
  newThresholds[index] = threshValue;
94
94
  if (newThresholds[0] >= newThresholds[1] || newThresholds[1] >= newThresholds[2] || newThresholds[2] >= newThresholds[3]) {
95
- node.status({ fill: "red", shape: "ring", text: "invalid threshold order" });
95
+ utils.setStatusError(node, "invalid threshold order");
96
96
  if (done) done();
97
97
  return;
98
98
  }
99
- node.runtime[`threshold${index + 1}`] = threshValue;
100
- node.status({ fill: "green", shape: "dot", text: `${msg.context}: ${threshValue}` });
99
+ node[`threshold${index + 1}`] = threshValue;
100
+ utils.setStatusOK(node, `${msg.context}: ${threshValue}`);
101
101
  break;
102
102
  case "feedback1":
103
103
  case "feedback2":
104
104
  case "feedback3":
105
105
  case "feedback4":
106
106
  if (typeof msg.payload !== "boolean") {
107
- node.status({ fill: "red", shape: "ring", text: `invalid ${msg.context}` });
107
+ utils.setStatusError(node, `invalid ${msg.context}`);
108
108
  if (done) done();
109
109
  return;
110
110
  }
111
- node.runtime[msg.context] = msg.payload;
112
- node.status({ fill: "green", shape: "dot", text: `${msg.context}: ${msg.payload}` });
111
+ node[msg.context] = msg.payload;
112
+ utils.setStatusOK(node, `${msg.context}: ${msg.payload}`);
113
113
  break;
114
114
  default:
115
- node.status({ fill: "yellow", shape: "ring", text: "unknown context" });
115
+ utils.setStatusWarn(node, "unknown context");
116
116
  if (done) done("Unknown context");
117
117
  return;
118
118
  }
@@ -121,40 +121,40 @@ module.exports = function(RED) {
121
121
  // Handle input
122
122
  let inputValue;
123
123
  if (msg.hasOwnProperty("context")) {
124
- inputValue = node.runtime.lastInput;
124
+ inputValue = node.lastInput;
125
125
  } else {
126
126
  if (!msg.hasOwnProperty("payload")) {
127
- node.status({ fill: "red", shape: "ring", text: "missing payload" });
127
+ utils.setStatusError(node, "missing payload");
128
128
  if (done) done();
129
129
  return;
130
130
  }
131
131
  if (msg.payload === "kill") {
132
- inputValue = node.runtime.lastInput;
132
+ inputValue = node.lastInput;
133
133
  } else {
134
134
  inputValue = parseFloat(msg.payload);
135
135
  if (isNaN(inputValue)) {
136
- node.status({ fill: "red", shape: "ring", text: "invalid payload" });
136
+ utils.setStatusError(node, "invalid payload");
137
137
  if (done) done();
138
138
  return;
139
139
  }
140
- node.runtime.lastInput = inputValue;
140
+ node.lastInput = inputValue;
141
141
  }
142
142
  }
143
143
 
144
144
  // Kill switch
145
145
  if (msg.payload === "kill") {
146
- node.runtime.out1 = node.runtime.out2 = node.runtime.out3 = node.runtime.out4 = false;
147
- node.runtime.dOn = 0;
148
- node.runtime.lastOutputs = [false, false, false, false];
149
- node.status({ fill: "red", shape: "dot", text: "kill: all off" });
146
+ node.out1 = node.out2 = node.out3 = node.out4 = false;
147
+ node.dOn = 0;
148
+ node.lastOutputs = [false, false, false, false];
149
+ utils.setStatusError(node, "kill: all off");
150
150
  send([{ payload: false }, { payload: false }, { payload: false }, { payload: false }]);
151
151
  if (done) done();
152
152
  return;
153
153
  }
154
154
 
155
155
  // Validate thresholds
156
- if (node.runtime.threshold1 >= node.runtime.threshold2 || node.runtime.threshold2 >= node.runtime.threshold3 || node.runtime.threshold3 >= node.runtime.threshold4) {
157
- node.status({ fill: "red", shape: "ring", text: "invalid threshold order" });
156
+ if (node.threshold1 >= node.threshold2 || node.threshold2 >= node.threshold3 || node.threshold3 >= node.threshold4) {
157
+ utils.setStatusError(node, "invalid threshold order");
158
158
  if (done) done();
159
159
  return;
160
160
  }
@@ -163,101 +163,93 @@ module.exports = function(RED) {
163
163
  let newMsg = [null, null, null, null];
164
164
  let numStagesOn = 0;
165
165
 
166
- if (!node.runtime.enable) {
167
- if (node.runtime.out4) {
168
- node.runtime.out4 = false;
166
+ if (!node.enable) {
167
+ if (node.out4) {
168
+ node.out4 = false;
169
169
  newMsg[3] = { payload: false };
170
- } else if (node.runtime.out3) {
171
- node.runtime.out3 = false;
170
+ } else if (node.out3) {
171
+ node.out3 = false;
172
172
  newMsg[2] = { payload: false };
173
- } else if (node.runtime.out2) {
174
- node.runtime.out2 = false;
173
+ } else if (node.out2) {
174
+ node.out2 = false;
175
175
  newMsg[1] = { payload: false };
176
- } else if (node.runtime.out1) {
177
- node.runtime.out1 = false;
176
+ } else if (node.out1) {
177
+ node.out1 = false;
178
178
  newMsg[0] = { payload: false };
179
179
  }
180
180
  numStagesOn = 0;
181
181
  } else {
182
- let newOut1 = node.runtime.out1;
183
- let newOut2 = node.runtime.out2;
184
- let newOut3 = node.runtime.out3;
185
- let newOut4 = node.runtime.out4;
182
+ let newOut1 = node.out1;
183
+ let newOut2 = node.out2;
184
+ let newOut3 = node.out3;
185
+ let newOut4 = node.out4;
186
186
 
187
187
  // Output 1
188
- if (node.runtime.out1) {
189
- if (inputValue < (node.runtime.threshold1 - node.runtime.hysteresis) && (node.runtime.feedback1 && !node.runtime.out2)) {
188
+ if (node.out1) {
189
+ if (inputValue < (node.threshold1 - node.hysteresis) && (node.feedback1 && !node.out2)) {
190
190
  newOut1 = false;
191
191
  }
192
- } else if (inputValue >= node.runtime.threshold1) {
192
+ } else if (inputValue >= node.threshold1) {
193
193
  newOut1 = true;
194
194
  }
195
195
 
196
196
  // Output 2
197
- if (node.runtime.out2) {
198
- if (inputValue < (node.runtime.threshold2 - node.runtime.hysteresis) && (node.runtime.feedback2 && !node.runtime.out3)) {
197
+ if (node.out2) {
198
+ if (inputValue < (node.threshold2 - node.hysteresis) && (node.feedback2 && !node.out3)) {
199
199
  newOut2 = false;
200
200
  }
201
- } else if (inputValue >= node.runtime.threshold2 && node.runtime.feedback1) {
201
+ } else if (inputValue >= node.threshold2 && node.feedback1) {
202
202
  newOut2 = true;
203
203
  }
204
204
 
205
205
  // Output 3
206
- if (node.runtime.out3) {
207
- if (inputValue < (node.runtime.threshold3 - node.runtime.hysteresis) && (node.runtime.feedback3 && !node.runtime.out4)) {
206
+ if (node.out3) {
207
+ if (inputValue < (node.threshold3 - node.hysteresis) && (node.feedback3 && !node.out4)) {
208
208
  newOut3 = false;
209
209
  }
210
- } else if (inputValue >= node.runtime.threshold3 && node.runtime.feedback2) {
210
+ } else if (inputValue >= node.threshold3 && node.feedback2) {
211
211
  newOut3 = true;
212
212
  }
213
213
 
214
214
  // Output 4
215
- if (node.runtime.out4) {
216
- if (inputValue < (node.runtime.threshold4 - node.runtime.hysteresis) && node.runtime.feedback4) {
215
+ if (node.out4) {
216
+ if (inputValue < (node.threshold4 - node.hysteresis) && node.feedback4) {
217
217
  newOut4 = false;
218
218
  }
219
- } else if (inputValue >= node.runtime.threshold4 && node.runtime.feedback3) {
219
+ } else if (inputValue >= node.threshold4 && node.feedback3) {
220
220
  newOut4 = true;
221
221
  }
222
222
 
223
223
  // Prioritize lowest stage change
224
- if (newOut1 !== node.runtime.out1) {
225
- node.runtime.out1 = newOut1;
226
- newMsg = [{ payload: node.runtime.out1 }, null, null, null];
227
- } else if (newOut2 !== node.runtime.out2) {
228
- node.runtime.out2 = newOut2;
229
- newMsg = [null, { payload: node.runtime.out2 }, null, null];
230
- } else if (newOut3 !== node.runtime.out3) {
231
- node.runtime.out3 = newOut3;
232
- newMsg = [null, null, { payload: node.runtime.out3 }, null];
233
- } else if (newOut4 !== node.runtime.out4) {
234
- node.runtime.out4 = newOut4;
235
- newMsg = [null, null, null, { payload: node.runtime.out4 }];
224
+ if (newOut1 !== node.out1) {
225
+ node.out1 = newOut1;
226
+ newMsg = [{ payload: node.out1 }, null, null, null];
227
+ } else if (newOut2 !== node.out2) {
228
+ node.out2 = newOut2;
229
+ newMsg = [null, { payload: node.out2 }, null, null];
230
+ } else if (newOut3 !== node.out3) {
231
+ node.out3 = newOut3;
232
+ newMsg = [null, null, { payload: node.out3 }, null];
233
+ } else if (newOut4 !== node.out4) {
234
+ node.out4 = newOut4;
235
+ newMsg = [null, null, null, { payload: node.out4 }];
236
236
  }
237
237
 
238
- numStagesOn = (node.runtime.out1 ? 1 : 0) + (node.runtime.out2 ? 1 : 0) + (node.runtime.out3 ? 1 : 0) + (node.runtime.out4 ? 1 : 0);
238
+ numStagesOn = (node.out1 ? 1 : 0) + (node.out2 ? 1 : 0) + (node.out3 ? 1 : 0) + (node.out4 ? 1 : 0);
239
239
  }
240
240
 
241
241
  // Update state
242
- node.runtime.dOn = numStagesOn;
242
+ node.dOn = numStagesOn;
243
243
 
244
244
  // Check if outputs changed
245
- const outputsChanged = newMsg.some((msg, i) => msg !== null && msg.payload !== node.runtime.lastOutputs[i]);
246
- node.runtime.lastOutputs = [node.runtime.out1, node.runtime.out2, node.runtime.out3, node.runtime.out4];
245
+ const outputsChanged = newMsg.some((msg, i) => msg !== null && msg.payload !== node.lastOutputs[i]);
246
+ node.lastOutputs = [node.out1, node.out2, node.out3, node.out4];
247
247
 
248
248
  if (outputsChanged) {
249
- node.status({
250
- fill: "blue",
251
- shape: "dot",
252
- text: `in: ${inputValue.toFixed(2)}, out: [${node.runtime.out1}, ${node.runtime.out2}, ${node.runtime.out3}, ${node.runtime.out4}]`
253
- });
249
+ utils.setStatusChanged(node, `in: ${inputValue.toFixed(2)}, out: [${node.out1}, ${node.out2}, ${node.out3}, ${node.out4}]`);
254
250
  send(newMsg);
255
251
  } else {
256
- node.status({
257
- fill: "blue",
258
- shape: "ring",
259
- text: `in: ${inputValue.toFixed(2)}, out: [${node.runtime.out1}, ${node.runtime.out2}, ${node.runtime.out3}, ${node.runtime.out4}]`
260
- });
252
+ utils.setStatusUnchanged(node, `in: ${inputValue.toFixed(2)}, out: [${node.out1}, ${node.out2}, ${node.out3}, ${node.out4}]`);
261
253
  }
262
254
 
263
255
  if (done) done();
@@ -7,10 +7,9 @@ module.exports = function(RED) {
7
7
  node.isBusy = false;
8
8
 
9
9
  // Initialize runtime state
10
- node.runtime = {
11
- name: config.name,
12
- max: parseFloat(config.max)
13
- };
10
+ // Initialize state
11
+ node.name = config.name;
12
+ node.max = parseFloat(config.max);
14
13
 
15
14
  // Store last output value for status
16
15
  let lastOutput = null;
@@ -20,7 +19,7 @@ module.exports = function(RED) {
20
19
 
21
20
  // Guard against invalid message
22
21
  if (!msg) {
23
- node.status({ fill: "red", shape: "ring", text: "invalid message" });
22
+ utils.setStatusError(node, "invalid message");
24
23
  if (done) done();
25
24
  return;
26
25
  }
@@ -31,7 +30,7 @@ module.exports = function(RED) {
31
30
  // Check busy lock
32
31
  if (node.isBusy) {
33
32
  // Update status to let user know they are pushing too fast
34
- node.status({ fill: "yellow", shape: "ring", text: "busy - dropped msg" });
33
+ utils.setStatusBusy(node, "busy - dropped msg");
35
34
  if (done) done();
36
35
  return;
37
36
  }
@@ -46,13 +45,13 @@ module.exports = function(RED) {
46
45
  utils.requiresEvaluation(config.maxType)
47
46
  ? utils.evaluateNodeProperty(config.max, config.maxType, node, msg)
48
47
  .then(val => parseFloat(val))
49
- : Promise.resolve(node.runtime.max),
48
+ : Promise.resolve(node.max),
50
49
  );
51
50
 
52
51
  const results = await Promise.all(evaluations);
53
52
 
54
53
  // Update runtime with evaluated values
55
- if (!isNaN(results[0])) node.runtime.max = results[0];
54
+ if (!isNaN(results[0])) node.max = results[0];
56
55
  } catch (err) {
57
56
  node.error(`Error evaluating properties: ${err.message}`);
58
57
  if (done) done();
@@ -63,8 +62,8 @@ module.exports = function(RED) {
63
62
  }
64
63
 
65
64
  // Validate values
66
- if (isNaN(node.runtime.max)) {
67
- node.status({ fill: "red", shape: "ring", text: "invalid evaluated values" });
65
+ if (isNaN(node.max)) {
66
+ utils.setStatusError(node, "invalid evaluated values");
68
67
  if (done) done();
69
68
  return;
70
69
  }
@@ -72,23 +71,22 @@ module.exports = function(RED) {
72
71
  // Handle context updates
73
72
  if (msg.hasOwnProperty("context")) {
74
73
  if (!msg.hasOwnProperty("payload")) {
75
- node.status({ fill: "red", shape: "ring", text: "missing payload for max" });
74
+ utils.setStatusError(node, "missing payload for max");
76
75
  if (done) done();
77
76
  return;
78
77
  }
79
78
  if (msg.context === "max" || msg.context === "setpoint") {
80
79
  const maxValue = parseFloat(msg.payload);
81
80
  if (!isNaN(maxValue) && maxValue >= 0) {
82
- node.runtime.max = maxValue;
83
- node.status({ fill: "green", shape: "dot", text: `max: ${maxValue}`
84
- });
81
+ node.max = maxValue;
82
+ utils.setStatusOK(node, `max: ${maxValue}`);
85
83
  } else {
86
- node.status({ fill: "red", shape: "ring", text: "invalid max" });
84
+ utils.setStatusError(node, "invalid max");
87
85
  }
88
86
  if (done) done();
89
87
  return;
90
88
  } else {
91
- node.status({ fill: "yellow", shape: "ring", text: "unknown context" });
89
+ utils.setStatusWarn(node, "unknown context");
92
90
  if (done) done();
93
91
  return;
94
92
  }
@@ -96,28 +94,30 @@ module.exports = function(RED) {
96
94
 
97
95
  // Validate input payload
98
96
  if (!msg.hasOwnProperty("payload")) {
99
- node.status({ fill: "red", shape: "ring", text: "missing payload" });
97
+ utils.setStatusError(node, "missing payload");
100
98
  if (done) done();
101
99
  return;
102
100
  }
103
101
 
104
- const inputValue = parseFloat(msg.payload);
105
- if (isNaN(inputValue)) {
106
- node.status({ fill: "red", shape: "ring", text: "invalid payload" });
102
+ const numVal = utils.validateNumericPayload(msg.payload);
103
+ if (!numVal.valid) {
104
+ utils.setStatusError(node, numVal.error);
107
105
  if (done) done();
108
106
  return;
109
107
  }
108
+ const inputValue = numVal.value;
110
109
 
111
110
  // Cap input at max
112
- const outputValue = Math.min(inputValue, node.runtime.max);
111
+ const outputValue = Math.min(inputValue, node.max);
113
112
 
114
113
  // Update status and send output
115
114
  msg.payload = outputValue;
116
- node.status({
117
- fill: "blue",
118
- shape: lastOutput === outputValue ? "ring" : "dot",
119
- text: `in: ${inputValue.toFixed(2)}, out: ${outputValue.toFixed(2)}`
120
- });
115
+ const statusText = `in: ${inputValue.toFixed(2)}, out: ${outputValue.toFixed(2)}`;
116
+ if (lastOutput === outputValue) {
117
+ utils.setStatusUnchanged(node, statusText);
118
+ } else {
119
+ utils.setStatusChanged(node, statusText);
120
+ }
121
121
  lastOutput = outputValue;
122
122
  send(msg);
123
123