@bldgblocks/node-red-contrib-control 0.1.37 → 0.2.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/LICENSE.md +38 -5
- package/README.md +10 -0
- package/nodes/accumulate-block.html +3 -3
- package/nodes/alarm-collector.html +11 -0
- package/nodes/alarm-collector.js +31 -5
- package/nodes/alarm-config.html +11 -6
- package/nodes/alarm-config.js +34 -35
- package/nodes/alarm-service.js +2 -2
- package/nodes/and-block.js +1 -1
- package/nodes/boolean-switch-block.html +27 -14
- package/nodes/boolean-switch-block.js +22 -12
- package/nodes/call-status-block.html +83 -56
- package/nodes/call-status-block.js +335 -248
- package/nodes/changeover-block.html +30 -31
- package/nodes/changeover-block.js +287 -389
- package/nodes/contextual-label-block.js +3 -3
- package/nodes/delay-block.js +74 -13
- package/nodes/global-getter.html +173 -12
- package/nodes/global-getter.js +29 -14
- package/nodes/global-setter.html +37 -0
- package/nodes/global-setter.js +96 -14
- package/nodes/history-buffer.js +32 -27
- package/nodes/history-collector.html +3 -1
- package/nodes/history-collector.js +4 -4
- package/nodes/history-config.html +8 -2
- package/nodes/network-point-read.js +6 -1
- package/nodes/network-point-register.html +1 -1
- package/nodes/network-service-bridge.js +43 -11
- package/nodes/network-service-registry.html +236 -27
- package/nodes/network-service-registry.js +1 -1
- package/nodes/or-block.js +1 -1
- package/nodes/priority-block.js +1 -1
- package/nodes/tstat-block.html +34 -79
- package/nodes/tstat-block.js +223 -345
- package/nodes/utils.js +1 -1
- package/package.json +90 -75
|
@@ -5,16 +5,22 @@
|
|
|
5
5
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
6
6
|
</div>
|
|
7
7
|
<div class="form-row">
|
|
8
|
-
<label for="node-input-
|
|
9
|
-
<input type="text" id="node-input-
|
|
8
|
+
<label for="node-input-callValue" title="Call (request) signal — typed input (bool, msg, flow, global)"><i class="fa fa-sign-in"></i> Call Value</label>
|
|
9
|
+
<input type="text" id="node-input-callValue" placeholder="payload">
|
|
10
|
+
<input type="hidden" id="node-input-callValueType">
|
|
10
11
|
</div>
|
|
11
12
|
<div class="form-row">
|
|
12
|
-
<label for="node-input-
|
|
13
|
-
<input type="text" id="node-input-
|
|
13
|
+
<label for="node-input-statusValue" title="Status (response) signal — typed input (bool, msg, flow, global)"><i class="fa fa-sign-out"></i> Status Value</label>
|
|
14
|
+
<input type="text" id="node-input-statusValue" placeholder="status">
|
|
15
|
+
<input type="hidden" id="node-input-statusValueType">
|
|
14
16
|
</div>
|
|
15
17
|
<div class="form-row">
|
|
16
|
-
<label for="node-input-statusTimeout" title="Time to wait for status response (seconds,
|
|
17
|
-
<input type="number" id="node-input-statusTimeout" placeholder="30" min="0
|
|
18
|
+
<label for="node-input-statusTimeout" title="Time to wait for initial status response after call activates (seconds, 0=disabled)"><i class="fa fa-clock-o"></i> Status Timeout</label>
|
|
19
|
+
<input type="number" id="node-input-statusTimeout" placeholder="30" min="0" step="any">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="form-row">
|
|
22
|
+
<label for="node-input-heartbeatTimeout" title="Heartbeat window for continuous status monitoring (seconds, 0=disabled)"><i class="fa fa-heartbeat"></i> Heartbeat Timeout</label>
|
|
23
|
+
<input type="number" id="node-input-heartbeatTimeout" placeholder="0" min="0" step="any">
|
|
18
24
|
</div>
|
|
19
25
|
<div class="form-row">
|
|
20
26
|
<label for="node-input-clearDelay" title="Delay before clearing status and alarm after call ends (seconds, 0=immediate)"><i class="fa fa-hourglass"></i> Clear Delay</label>
|
|
@@ -22,27 +28,31 @@
|
|
|
22
28
|
</div>
|
|
23
29
|
<div class="form-row">
|
|
24
30
|
<label for="node-input-debounce" title="Debounce status flicker (milliseconds, 0=disabled)"><i class="fa fa-filter"></i> Debounce</label>
|
|
25
|
-
<input type="number" id="node-input-debounce" placeholder="
|
|
31
|
+
<input type="number" id="node-input-debounce" placeholder="0" min="0" step="any">
|
|
26
32
|
</div>
|
|
27
33
|
<div class="form-row">
|
|
28
|
-
<label for="node-input-
|
|
29
|
-
<input type="
|
|
34
|
+
<label for="node-input-noStatusOnRun" title="Alarm if no status received during call (boolean)"><i class="fa fa-exclamation-triangle"></i> No Status On Run</label>
|
|
35
|
+
<input type="checkbox" id="node-input-noStatusOnRun" style="width: auto; vertical-align: middle;">
|
|
30
36
|
</div>
|
|
31
37
|
<div class="form-row">
|
|
32
38
|
<label for="node-input-runLostStatus" title="Alarm if status is lost during call (boolean)"><i class="fa fa-exclamation-triangle"></i> Run Lost Status</label>
|
|
33
39
|
<input type="checkbox" id="node-input-runLostStatus" style="width: auto; vertical-align: middle;">
|
|
34
40
|
</div>
|
|
35
41
|
<div class="form-row">
|
|
36
|
-
<label for="node-input-
|
|
37
|
-
<input type="checkbox" id="node-input-
|
|
42
|
+
<label for="node-input-statusWithoutCall" title="Alarm if equipment status is active without a call signal (boolean)"><i class="fa fa-exclamation-triangle"></i> Status Without Call</label>
|
|
43
|
+
<input type="checkbox" id="node-input-statusWithoutCall" style="width: auto; vertical-align: middle;">
|
|
44
|
+
</div>
|
|
45
|
+
<div class="form-row">
|
|
46
|
+
<label for="node-input-noStatusOnRunMessage" title="Message for no status on run alarm (string)"><i class="fa fa-comment"></i> No Status Message</label>
|
|
47
|
+
<input type="text" id="node-input-noStatusOnRunMessage" placeholder="No status received during run">
|
|
38
48
|
</div>
|
|
39
49
|
<div class="form-row">
|
|
40
50
|
<label for="node-input-runLostStatusMessage" title="Message for run lost status alarm (string)"><i class="fa fa-comment"></i> Run Lost Message</label>
|
|
41
51
|
<input type="text" id="node-input-runLostStatusMessage" placeholder="Status lost during run">
|
|
42
52
|
</div>
|
|
43
53
|
<div class="form-row">
|
|
44
|
-
<label for="node-input-
|
|
45
|
-
<input type="text" id="node-input-
|
|
54
|
+
<label for="node-input-statusWithoutCallMessage" title="Message for status without call alarm (string)"><i class="fa fa-comment"></i> Without Call Message</label>
|
|
55
|
+
<input type="text" id="node-input-statusWithoutCallMessage" placeholder="Status active without call">
|
|
46
56
|
</div>
|
|
47
57
|
</script>
|
|
48
58
|
|
|
@@ -53,16 +63,20 @@
|
|
|
53
63
|
color: "#301934",
|
|
54
64
|
defaults: {
|
|
55
65
|
name: { value: "" },
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
callValue: { value: "payload" },
|
|
67
|
+
callValueType: { value: "msg" },
|
|
68
|
+
statusValue: { value: "status" },
|
|
69
|
+
statusValueType: { value: "msg" },
|
|
70
|
+
statusTimeout: { value: 30, required: true, validate: function(v) { return !isNaN(parseFloat(v)) && parseFloat(v) >= 0; } },
|
|
71
|
+
heartbeatTimeout: { value: 0, required: true, validate: function(v) { return !isNaN(parseFloat(v)) && parseFloat(v) >= 0; } },
|
|
59
72
|
clearDelay: { value: 10, required: true, validate: function(v) { return !isNaN(parseFloat(v)) && parseFloat(v) >= 0; } },
|
|
60
|
-
debounce: { value:
|
|
61
|
-
heartbeatTimeout: { value: 30, required: true, validate: function(v) { return !isNaN(parseFloat(v)) && parseFloat(v) >= 0; } },
|
|
73
|
+
debounce: { value: 0, required: true, validate: function(v) { return !isNaN(parseFloat(v)) && parseFloat(v) >= 0; } },
|
|
62
74
|
runLostStatus: { value: false },
|
|
63
75
|
noStatusOnRun: { value: true },
|
|
76
|
+
statusWithoutCall: { value: true },
|
|
64
77
|
runLostStatusMessage: { value: "Status lost during run" },
|
|
65
|
-
noStatusOnRunMessage: { value: "No status received during run" }
|
|
78
|
+
noStatusOnRunMessage: { value: "No status received during run" },
|
|
79
|
+
statusWithoutCallMessage: { value: "Status active without call" }
|
|
66
80
|
},
|
|
67
81
|
inputs: 1,
|
|
68
82
|
outputs: 1,
|
|
@@ -72,6 +86,24 @@
|
|
|
72
86
|
paletteLabel: "call status",
|
|
73
87
|
label: function() {
|
|
74
88
|
return this.name || "call status";
|
|
89
|
+
},
|
|
90
|
+
oneditprepare: function() {
|
|
91
|
+
const node = this;
|
|
92
|
+
try {
|
|
93
|
+
$("#node-input-callValue").typedInput({
|
|
94
|
+
default: "msg",
|
|
95
|
+
types: ["msg", "flow", "global", "bool"],
|
|
96
|
+
typeField: "#node-input-callValueType"
|
|
97
|
+
}).typedInput("type", node.callValueType || "msg").typedInput("value", node.callValue || "payload");
|
|
98
|
+
|
|
99
|
+
$("#node-input-statusValue").typedInput({
|
|
100
|
+
default: "msg",
|
|
101
|
+
types: ["msg", "flow", "global", "bool"],
|
|
102
|
+
typeField: "#node-input-statusValueType"
|
|
103
|
+
}).typedInput("type", node.statusValueType || "msg").typedInput("value", node.statusValue || "status");
|
|
104
|
+
} catch(e) {
|
|
105
|
+
console.error("Error preparing call-status-block editor:", e);
|
|
106
|
+
}
|
|
75
107
|
}
|
|
76
108
|
});
|
|
77
109
|
</script>
|
|
@@ -82,8 +114,11 @@ Monitors call and status signals to detect equipment faults, communication losse
|
|
|
82
114
|
|
|
83
115
|
### Inputs
|
|
84
116
|
|
|
85
|
-
|
|
86
|
-
|
|
117
|
+
Both **Call Value** and **Status Value** are **typed inputs** — they can read from `msg` properties, `flow` variables, `global` variables, or static `bool` values.
|
|
118
|
+
|
|
119
|
+
Every incoming message triggers the node to evaluate both values and process state transitions.
|
|
120
|
+
|
|
121
|
+
: context (string) : Optional. Send `msg.context = "reset"` with `msg.payload = true` to reset all state and clear alarms.
|
|
87
122
|
|
|
88
123
|
### Outputs
|
|
89
124
|
|
|
@@ -93,60 +128,52 @@ Monitors call and status signals to detect equipment faults, communication losse
|
|
|
93
128
|
|
|
94
129
|
### Properties
|
|
95
130
|
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
131
|
+
- **Call Value** (typed input) — Source of the call (request) signal. Default: `msg.payload`. Can be `msg`, `flow`, `global`, or `bool`.
|
|
132
|
+
- **Status Value** (typed input) — Source of the status (response) signal. Default: `msg.status`. Can be `msg`, `flow`, `global`, or `bool`.
|
|
133
|
+
- **Status Timeout** (number) — Seconds to wait for the *first* status=true after call activates (0=disabled). This is a one-shot timer for initial equipment response. Default: `30`.
|
|
134
|
+
- **Heartbeat Timeout** (number) — Seconds for ongoing status freshness monitoring while running. Each status=true resets the timer. If it expires without a refresh, status is considered lost (0=disabled). Default: `0`.
|
|
135
|
+
- **Clear Delay** (number) — Seconds to hold actual state after call deactivated (0=immediate). Default: `10`.
|
|
136
|
+
- **Debounce** (number) — Milliseconds to filter status value changes (0=disabled). Default: `0`.
|
|
137
|
+
- **No Status On Run** (checkbox) — Alarm if no status response within initial timeout. Default: checked.
|
|
138
|
+
- **Run Lost Status** (checkbox) — Alarm if equipment status becomes false while call is true. Default: unchecked.
|
|
139
|
+
- **Status Without Call** (checkbox) — Alarm if equipment status is active without a call signal. Default: checked.
|
|
140
|
+
- **No Status Message** (string) — Alarm text for no status. Default: `"No status received during run"`.
|
|
141
|
+
- **Run Lost Message** (string) — Alarm text for status lost. Default: `"Status lost during run"`.
|
|
142
|
+
- **Without Call Message** (string) — Alarm text for status without call. Default: `"Status active without call"`.
|
|
107
143
|
|
|
108
144
|
### Details
|
|
109
145
|
|
|
110
|
-
The block implements a 4-state controller: IDLE (call=false), WAITING_FOR_STATUS (call=true, status pending), RUNNING (call=true, status=true), and STATUS_LOST (call=true, status=false).
|
|
146
|
+
The block implements a 4-state controller: **IDLE** (call=false), **WAITING_FOR_STATUS** (call=true, status pending), **RUNNING** (call=true, status=true), and **STATUS_LOST** (call=true, status=false after previously being true).
|
|
111
147
|
|
|
112
|
-
|
|
148
|
+
On every incoming message, the node evaluates both the call and status typed inputs simultaneously. This means a single message can carry both signals (e.g., `msg.payload` for call and `msg.status` for equipment feedback).
|
|
113
149
|
|
|
114
|
-
|
|
150
|
+
**Heartbeat refresh**: Repeated status=true values refresh the heartbeat timer even though the value hasn't changed. This is critical — equipment that continuously reports `status: true` must keep the heartbeat alive.
|
|
115
151
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Debounce collapses rapid status changes within the configured window into a single state transition, preventing false alarms from sensor noise. All alarm conditions include 100ms hysteresis to prevent false triggers.
|
|
119
|
-
|
|
120
|
-
#### Heartbeat Monitoring
|
|
121
|
-
|
|
122
|
-
When call=true and heartbeatTimeout > 0, the block continuously verifies that status updates arrive within the heartbeat window. This detects communication loss or equipment failures mid-cycle. Set heartbeatTimeout=0 to disable this feature.
|
|
152
|
+
**Debounce** only delays processing of status *value changes*. Same-value status updates always refresh the heartbeat immediately.
|
|
123
153
|
|
|
124
154
|
#### Alarm Conditions
|
|
125
155
|
|
|
126
|
-
|
|
156
|
+
1. **No Status Response** (hysteresis: statusTimeout seconds) — Triggered when call=true but no status arrives within initial timeout.
|
|
127
157
|
|
|
128
|
-
|
|
158
|
+
2. **Status Lost During Run** (hysteresis: 100ms) — Triggered when call=true, status was true, but status goes false mid-cycle. Also triggered by heartbeat timeout if enabled.
|
|
129
159
|
|
|
130
|
-
Status
|
|
160
|
+
3. **Status Active Without Call** (hysteresis: 100ms) — Triggered when status=true but call=false (and no clearTimer running), indicating unexpected equipment activity.
|
|
131
161
|
|
|
132
|
-
Status Not Clearing (
|
|
162
|
+
4. **Status Not Clearing** (hysteresis: clearDelay+1 seconds) — Triggered when call=false but status remains true beyond the clear delay window.
|
|
133
163
|
|
|
134
164
|
#### HVAC Scenarios
|
|
135
165
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Scenario 2: VAV box with wireless controller. Send `{payload: true}` to activate damper. If wireless module not responding, No Status alarm triggers after 10s. Configuration: Status Timeout=10s, Heartbeat Timeout=0 (heartbeat disabled), No Status On Run=true.
|
|
166
|
+
**Chiller with feedback**: Call Value = `msg.payload`, Status Value = `flow.chillerStatus`. Send `{payload: true}` to request. Chiller writes status to flow variable. Config: Status Timeout=30s, Heartbeat=30s, Run Lost Status=checked.
|
|
139
167
|
|
|
140
|
-
|
|
168
|
+
**VAV box wireless**: Call Value = `msg.payload`, Status Value = `msg.status`. Config: Status Timeout=10s, Heartbeat=0 (disabled), No Status On Run=checked.
|
|
141
169
|
|
|
142
|
-
|
|
170
|
+
**Pump with startup lag**: Call Value = `msg.payload`, Status Value = `global.pumpRunning`. Config: Status Timeout=8s, Heartbeat=15s, Clear Delay=3s, Debounce=200ms.
|
|
143
171
|
|
|
144
172
|
### Status
|
|
145
|
-
- Green (dot):
|
|
146
|
-
- Blue (
|
|
147
|
-
-
|
|
148
|
-
- Red (ring):
|
|
149
|
-
- Yellow (ring): Warning
|
|
173
|
+
- Green (dot): Running normally (call=ON, status=ON)
|
|
174
|
+
- Blue (ring): Idle (call=OFF, status=OFF)
|
|
175
|
+
- Yellow (ring): Waiting/warning state
|
|
176
|
+
- Red (ring): Alarm active
|
|
150
177
|
|
|
151
178
|
### References
|
|
152
179
|
|