@bitpoolos/edge-bacnet 1.5.3 → 1.6.1
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/CHANGELOG.md +155 -10
- package/bacnet_client.js +123 -107
- package/bacnet_gateway.html +22 -6
- package/bacnet_gateway.js +346 -250
- package/bacnet_inspector.html +43 -0
- package/bacnet_inspector.js +1420 -0
- package/bacnet_inspector_worker.js +535 -0
- package/bacnet_read.html +27 -27
- package/bacnet_read.js +0 -3
- package/common.js +201 -38
- package/examples/1-Discover-Read.json +170 -1
- package/examples/2-Discover-Write.json +164 -1
- package/examples/3-Discover-Read-Write.json +227 -1
- package/examples/4-Inspector.json +368 -0
- package/inspector.html +455 -0
- package/package.json +6 -2
- package/resources/Logo_Simplified_Positive.svg +32 -0
- package/resources/downloadAsHtml.js +656 -0
- package/resources/icons/device-id-change-icon.svg +4 -0
- package/resources/icons/device-id-conflict-icon.svg +4 -0
- package/resources/icons/favicon.ico +0 -0
- package/resources/icons/points-error-icon.svg +4 -0
- package/resources/icons/points-missing-icon.svg +4 -0
- package/resources/icons/points-ok-icon.svg +4 -0
- package/resources/icons/points-unmapped-icon.svg +5 -0
- package/resources/icons/points-warning-icon.svg +4 -0
- package/resources/inspector.css +25312 -0
- package/resources/inspectorStyle.css +254 -0
- package/resources/inspectorStyles.css +503 -0
- package/resources/primevue.min.js +1 -0
- package/resources/style.css +17 -1
- package/resources/vue3513.global.prod.js +9 -0
- package/ssrHtmlExporter.js +537 -0
- package/treeBuilder.js +3 -3
package/bacnet_gateway.js
CHANGED
|
@@ -15,6 +15,7 @@ module.exports = function (RED) {
|
|
|
15
15
|
|
|
16
16
|
//bacnet local device info
|
|
17
17
|
this.localDeviceAddress = config.local_device_address;
|
|
18
|
+
this.local_interface_name = config.local_interface_name;
|
|
18
19
|
this.local_device_port = config.local_device_port;
|
|
19
20
|
this.apduSize = config.apduSize;
|
|
20
21
|
this.maxSegments = config.maxSegments;
|
|
@@ -46,126 +47,156 @@ module.exports = function (RED) {
|
|
|
46
47
|
//determines whether or not to log a found device on whoIs response
|
|
47
48
|
this.toLogIam = config.toLogIam;
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
node.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
nodeContext.set("bacnetClient", node.bacnetClient);
|
|
50
|
+
try {
|
|
51
|
+
node.bacnetConfig = new BacnetClientConfig(
|
|
52
|
+
node.apduTimeout,
|
|
53
|
+
node.localDeviceAddress,
|
|
54
|
+
node.local_device_port,
|
|
55
|
+
node.apduSize,
|
|
56
|
+
node.maxSegments,
|
|
57
|
+
node.broadCastAddr,
|
|
58
|
+
node.discover_polling_schedule,
|
|
59
|
+
node.toRestartNodeRed,
|
|
60
|
+
node.deviceId,
|
|
61
|
+
node.manual_instance_range_enabled,
|
|
62
|
+
node.manual_instance_range_start,
|
|
63
|
+
node.manual_instance_range_end,
|
|
64
|
+
node.device_read_schedule,
|
|
65
|
+
node.retries,
|
|
66
|
+
node.cacheFileEnabled,
|
|
67
|
+
node.sanitise_device_schedule,
|
|
68
|
+
node.portRangeRegisters.filter((ele) => ele.enabled === true)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (typeof node.bacnetClient !== "undefined") {
|
|
72
|
+
node.bacnetClient.removeAllListeners();
|
|
73
|
+
bindEventListeners();
|
|
74
|
+
node.bacnetClient.reinitializeClient(node.bacnetConfig);
|
|
75
|
+
} else {
|
|
76
|
+
node.bacnetClient = new BacnetClient(node.bacnetConfig);
|
|
77
|
+
nodeContext.set("bacnetClient", node.bacnetClient);
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
nodeContext.set("serverWritePropEvent", false);
|
|
80
|
+
}
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
node.bacnetClient.scanMatrix = node.deviceRangeRegisters.filter((ele) => ele.enabled === true);
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
if (node.bacnetServerEnabled == true && node.bacnetClient && node.bacnetServer) {
|
|
85
|
+
node.bacnetServer.deviceId = node.deviceId;
|
|
86
|
+
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
node.bacnetClient.bacnetServerEnabled = node.bacnetServerEnabled;
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
if (node.bacnetServerEnabled == true && node.bacnetClient) {
|
|
91
|
+
if (node.bacnetServer == null) {
|
|
92
|
+
node.bacnetServer = new BacnetServer(node.bacnetClient, node.deviceId, RED.version());
|
|
93
|
+
nodeContext.set("bacnetServer", node.bacnetServer);
|
|
94
|
+
}
|
|
95
|
+
} else if (node.bacnetServerEnabled == false) {
|
|
96
|
+
node.bacnetServer = null;
|
|
94
97
|
}
|
|
95
|
-
} else if (node.bacnetServerEnabled == false) {
|
|
96
|
-
node.bacnetServer = null;
|
|
97
|
-
}
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
// Clears event handlers of all listeners, avoiding memory leak
|
|
100
|
+
node.bacnetClient.removeAllListeners();
|
|
101
|
+
} catch (e) {
|
|
102
|
+
console.log("Bacnet gateway client init error: ", e);
|
|
103
|
+
}
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
let useDeviceName = outputType.useDeviceName;
|
|
113
|
-
if (outputType.json && !outputType.mqtt && !outputType.pointJson) {
|
|
114
|
-
//json
|
|
115
|
-
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
116
|
-
//simpleWithStatus
|
|
117
|
-
sendSimpleWithStatus(values, readNodeName, true, useDeviceName);
|
|
118
|
-
} else if (objectPropertyType.fullObject && !objectPropertyType.simplePayload && !objectPropertyType.simpleWithStatus) {
|
|
119
|
-
//fullObject
|
|
120
|
-
sendJsonAsMqtt(values, readNodeName, useDeviceName);
|
|
121
|
-
} else if (objectPropertyType.simplePayload && !objectPropertyType.fullObject && !objectPropertyType.simpleWithStatus) {
|
|
122
|
-
//simplePayload
|
|
123
|
-
sendSimpleJson(values, readNodeName, useDeviceName);
|
|
124
|
-
}
|
|
125
|
-
} else if (outputType.mqtt && !outputType.json && !outputType.pointJson) {
|
|
126
|
-
//mqtt
|
|
127
|
-
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
128
|
-
//simpleWithStatus
|
|
129
|
-
sendSimpleWithStatus(values, readNodeName, false, useDeviceName);
|
|
130
|
-
} else if (objectPropertyType.fullObject && !objectPropertyType.simplePayload && !objectPropertyType.simpleWithStatus) {
|
|
131
|
-
//fullObject
|
|
132
|
-
sendAsMqtt(values, readNodeName, useDeviceName);
|
|
133
|
-
} else if (objectPropertyType.simplePayload && !objectPropertyType.fullObject && !objectPropertyType.simpleWithStatus) {
|
|
134
|
-
//simplePayload
|
|
135
|
-
sendSimpleMqtt(values, readNodeName, useDeviceName);
|
|
105
|
+
try {
|
|
106
|
+
// Value response event handler for READ commands
|
|
107
|
+
node.bacnetClient.on("values", (values, outputType, objectPropertyType, readNodeName, deviceIndex, devicesToRead) => {
|
|
108
|
+
if (typeof values !== "undefined" && Object.keys(values).length) {
|
|
109
|
+
let publishText = `Publishing ${readNodeName} ${deviceIndex} / ${devicesToRead} `;
|
|
110
|
+
node.status({ fill: "blue", shape: "dot", text: publishText });
|
|
111
|
+
if (deviceIndex == devicesToRead) {
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
node.status({});
|
|
114
|
+
}, 3000);
|
|
136
115
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
116
|
+
let useDeviceName = outputType.useDeviceName;
|
|
117
|
+
if (outputType.json && !outputType.mqtt && !outputType.pointJson) {
|
|
118
|
+
//json
|
|
119
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
120
|
+
//simpleWithStatus
|
|
121
|
+
sendSimpleWithStatus(values, readNodeName, true, useDeviceName);
|
|
122
|
+
} else if (
|
|
123
|
+
objectPropertyType.fullObject &&
|
|
124
|
+
!objectPropertyType.simplePayload &&
|
|
125
|
+
!objectPropertyType.simpleWithStatus
|
|
126
|
+
) {
|
|
127
|
+
//fullObject
|
|
128
|
+
sendJsonAsMqtt(values, readNodeName, useDeviceName);
|
|
129
|
+
} else if (
|
|
130
|
+
objectPropertyType.simplePayload &&
|
|
131
|
+
!objectPropertyType.fullObject &&
|
|
132
|
+
!objectPropertyType.simpleWithStatus
|
|
133
|
+
) {
|
|
134
|
+
//simplePayload
|
|
135
|
+
sendSimpleJson(values, readNodeName, useDeviceName);
|
|
136
|
+
}
|
|
137
|
+
} else if (outputType.mqtt && !outputType.json && !outputType.pointJson) {
|
|
138
|
+
//mqtt
|
|
139
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
140
|
+
//simpleWithStatus
|
|
141
|
+
sendSimpleWithStatus(values, readNodeName, false, useDeviceName);
|
|
142
|
+
} else if (
|
|
143
|
+
objectPropertyType.fullObject &&
|
|
144
|
+
!objectPropertyType.simplePayload &&
|
|
145
|
+
!objectPropertyType.simpleWithStatus
|
|
146
|
+
) {
|
|
147
|
+
//fullObject
|
|
148
|
+
sendAsMqtt(values, readNodeName, useDeviceName);
|
|
149
|
+
} else if (
|
|
150
|
+
objectPropertyType.simplePayload &&
|
|
151
|
+
!objectPropertyType.fullObject &&
|
|
152
|
+
!objectPropertyType.simpleWithStatus
|
|
153
|
+
) {
|
|
154
|
+
//simplePayload
|
|
155
|
+
sendSimpleMqtt(values, readNodeName, useDeviceName);
|
|
156
|
+
}
|
|
157
|
+
} else if (outputType.pointJson && !outputType.json && !outputType.mqtt) {
|
|
158
|
+
//pointJson
|
|
159
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
160
|
+
//simpleWithStatus
|
|
161
|
+
sendSimpleWithStatus(values, readNodeName, false, useDeviceName);
|
|
162
|
+
} else if (
|
|
163
|
+
objectPropertyType.fullObject &&
|
|
164
|
+
!objectPropertyType.simplePayload &&
|
|
165
|
+
!objectPropertyType.simpleWithStatus
|
|
166
|
+
) {
|
|
167
|
+
//fullObject
|
|
168
|
+
sendIndividualMsgJson(values, readNodeName, useDeviceName);
|
|
169
|
+
} else if (
|
|
170
|
+
objectPropertyType.simplePayload &&
|
|
171
|
+
!objectPropertyType.fullObject &&
|
|
172
|
+
!objectPropertyType.simpleWithStatus
|
|
173
|
+
) {
|
|
174
|
+
//simplePayload
|
|
175
|
+
sendSimpleJsonPerPoint(values, readNodeName, useDeviceName);
|
|
176
|
+
}
|
|
148
177
|
}
|
|
149
178
|
}
|
|
150
|
-
}
|
|
151
|
-
});
|
|
179
|
+
});
|
|
152
180
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
181
|
+
// Who Is / Iam event handler
|
|
182
|
+
node.bacnetClient.on("deviceFound", (device) => {
|
|
183
|
+
if (node.toLogIam) {
|
|
184
|
+
if (device.source) {
|
|
185
|
+
node.warn(
|
|
186
|
+
`BACnet-MS/TP device found: ${device.deviceId} - ${device.address} - Network Id: ${device.source.net} - Mac: ${device.source.adr[0]}`
|
|
187
|
+
);
|
|
188
|
+
} else {
|
|
189
|
+
node.warn(`BACnet device found: ${device.deviceId} - ${device.address}`);
|
|
190
|
+
}
|
|
162
191
|
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
192
|
+
});
|
|
165
193
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
194
|
+
node.bacnetClient.on("bacnetErrorLog", (param1, param2) => {
|
|
195
|
+
logOut(param1, param2);
|
|
196
|
+
});
|
|
197
|
+
} catch (e) {
|
|
198
|
+
console.log("Bacnet node event handler error: ", e);
|
|
199
|
+
}
|
|
169
200
|
|
|
170
201
|
if (
|
|
171
202
|
node.nodeName !== "gateway" &&
|
|
@@ -179,75 +210,99 @@ module.exports = function (RED) {
|
|
|
179
210
|
}
|
|
180
211
|
}
|
|
181
212
|
|
|
182
|
-
if (
|
|
183
|
-
node.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
213
|
+
if (
|
|
214
|
+
node.bacnetServerEnabled == true &&
|
|
215
|
+
node.bacnetClient &&
|
|
216
|
+
node.bacnetServer &&
|
|
217
|
+
nodeContext.get("serverWritePropEvent") == false
|
|
218
|
+
) {
|
|
219
|
+
try {
|
|
220
|
+
node.bacnetServer.on("writeProperty", (topic, newValue) => {
|
|
221
|
+
let formattedTopic = topic;
|
|
222
|
+
if (
|
|
223
|
+
node.nodeName !== "gateway" &&
|
|
224
|
+
node.nodeName !== "" &&
|
|
225
|
+
node.nodeName !== "null" &&
|
|
226
|
+
node.nodeName !== "undefined" &&
|
|
227
|
+
typeof node.nodeName == "string"
|
|
228
|
+
) {
|
|
229
|
+
formattedTopic = `${node.nodeName}/BITPOOL_EDGE_BACNET_GATEWAY/BACNET_SERVER/${topic}`;
|
|
230
|
+
} else {
|
|
231
|
+
formattedTopic = `BITPOOL_EDGE_BACNET_GATEWAY/BACNET_SERVER/${topic}`;
|
|
232
|
+
}
|
|
196
233
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
234
|
+
node.send({ payload: newValue, topic: formattedTopic });
|
|
235
|
+
});
|
|
236
|
+
nodeContext.set("serverWritePropEvent", true);
|
|
237
|
+
} catch (e) {
|
|
238
|
+
console.log("Bacnet gateway node server writePoperty error: ", e);
|
|
239
|
+
}
|
|
200
240
|
}
|
|
201
241
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
node.bacnetServer
|
|
242
|
+
try {
|
|
243
|
+
node.on("input", function (msg) {
|
|
244
|
+
if (msg.topic && msg.payload !== null) {
|
|
245
|
+
if (node.bacnetServer) {
|
|
246
|
+
node.bacnetServer.addObject(msg.topic, msg.payload);
|
|
247
|
+
}
|
|
206
248
|
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (msg.type == "Read") {
|
|
210
|
-
node.bacnetClient.doRead(msg.options, msg.outputType, msg.objectPropertyType, msg.readNodeName);
|
|
211
|
-
} else if (msg.type == "Write") {
|
|
212
|
-
node.bacnetClient.doWrite(msg.value, msg.options);
|
|
213
|
-
} else if (msg.doDiscover == true) {
|
|
214
|
-
node.status({ fill: "blue", shape: "dot", text: "Sending global Who is" });
|
|
215
|
-
node.bacnetClient.globalWhoIs();
|
|
216
|
-
setTimeout(() => {
|
|
217
|
-
node.status({});
|
|
218
|
-
}, 2000);
|
|
219
|
-
} else if (msg.payload == "BindEvents") {
|
|
220
|
-
node.bacnetClient.removeAllListeners();
|
|
221
|
-
bindEventListeners();
|
|
222
|
-
} else if (msg.doUpdatePriorityDevices == true && msg.priorityDevices !== null) {
|
|
223
|
-
node.bacnetClient
|
|
224
|
-
.updatePriorityQueue(msg.priorityDevices)
|
|
225
|
-
.then(function (result) { })
|
|
226
|
-
.catch(function (error) {
|
|
227
|
-
logOut("Error updating priorityQueue: ", error);
|
|
228
|
-
});
|
|
229
|
-
} else if (msg.testFunc == true) {
|
|
230
|
-
node.bacnetClient.testFunction(msg.address, msg.port, msg.type, msg.instance, msg.property);
|
|
231
|
-
} else if (msg.applyDisplayNames) {
|
|
232
|
-
node.status({ fill: "blue", shape: "dot", text: "Updating display names" });
|
|
233
|
-
setTimeout(() => {
|
|
234
|
-
node.status({});
|
|
235
|
-
}, 2000);
|
|
236
249
|
|
|
237
|
-
|
|
238
|
-
.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
if (msg.type == "Read") {
|
|
251
|
+
node.bacnetClient.doRead(msg.options, msg.outputType, msg.objectPropertyType, msg.readNodeName);
|
|
252
|
+
} else if (msg.type == "Write") {
|
|
253
|
+
node.bacnetClient.doWrite(msg.value, msg.options);
|
|
254
|
+
} else if (msg.doDiscover == true) {
|
|
255
|
+
node.status({ fill: "blue", shape: "dot", text: "Sending global Who is" });
|
|
256
|
+
node.bacnetClient.globalWhoIs();
|
|
257
|
+
setTimeout(() => {
|
|
258
|
+
node.status({});
|
|
259
|
+
}, 2000);
|
|
260
|
+
} else if (msg.payload == "BindEvents") {
|
|
261
|
+
node.bacnetClient.removeAllListeners();
|
|
262
|
+
bindEventListeners();
|
|
263
|
+
} else if (msg.doUpdatePriorityDevices == true && msg.priorityDevices !== null) {
|
|
264
|
+
node.bacnetClient
|
|
265
|
+
.updatePriorityQueue(msg.priorityDevices)
|
|
266
|
+
.then(function (result) {})
|
|
267
|
+
.catch(function (error) {
|
|
268
|
+
logOut("Error updating priorityQueue: ", error);
|
|
269
|
+
});
|
|
270
|
+
} else if (msg.testFunc == true) {
|
|
271
|
+
node.bacnetClient.testFunction(msg.address, msg.port, msg.type, msg.instance, msg.property);
|
|
272
|
+
} else if (msg.applyDisplayNames) {
|
|
273
|
+
node.status({ fill: "blue", shape: "dot", text: "Updating display names" });
|
|
274
|
+
setTimeout(() => {
|
|
275
|
+
node.status({});
|
|
276
|
+
}, 2000);
|
|
277
|
+
|
|
278
|
+
node.bacnetClient
|
|
279
|
+
.applyDisplayNames(msg.pointsToRead)
|
|
280
|
+
.then(function (result) {})
|
|
281
|
+
.catch(function (error) {
|
|
282
|
+
logOut("Error in applyDisplayNames: ", error);
|
|
283
|
+
});
|
|
284
|
+
} else if (msg.forceUpdateDevices == true) {
|
|
285
|
+
node.bacnetClient.forceUpdateDevices(msg.deviceIdArray);
|
|
286
|
+
} else if (msg.reinitializeBacnetServer == true) {
|
|
287
|
+
if (node.bacnetServerEnabled == true && node.bacnetClient) {
|
|
288
|
+
node.bacnetServer.clearServerPoints();
|
|
289
|
+
if (msg.responseTopic) {
|
|
290
|
+
node.send({ topic: msg.responseTopic, payload: "Server sucessfully reinitialized" });
|
|
291
|
+
}
|
|
292
|
+
node.status({ fill: "blue", shape: "dot", text: "Reinitializing Server" });
|
|
293
|
+
setTimeout(() => {
|
|
294
|
+
node.status({});
|
|
295
|
+
}, 2000);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
247
299
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
300
|
+
node.on("close", function () {
|
|
301
|
+
//do nothing
|
|
302
|
+
});
|
|
303
|
+
} catch (e) {
|
|
304
|
+
console.log("Bacnet node event handler error: ", e);
|
|
305
|
+
}
|
|
251
306
|
|
|
252
307
|
//route handler for network data
|
|
253
308
|
RED.httpAdmin.get("/bitpool-bacnet-data/getNetworkTree", function (req, res) {
|
|
@@ -298,27 +353,33 @@ module.exports = function (RED) {
|
|
|
298
353
|
});
|
|
299
354
|
|
|
300
355
|
//route handler for the clear Bacnet server point function
|
|
301
|
-
RED.httpAdmin.post(
|
|
356
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/clearBacnetServerPoint", function (req, res) {
|
|
302
357
|
if (node.bacnetServerEnabled == true && node.bacnetClient) {
|
|
303
|
-
node.bacnetServer
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
358
|
+
node.bacnetServer
|
|
359
|
+
.clearServerPoint(req)
|
|
360
|
+
.then(function (result) {
|
|
361
|
+
res.send(result);
|
|
362
|
+
})
|
|
363
|
+
.catch(function (error) {
|
|
364
|
+
res.send(error);
|
|
365
|
+
});
|
|
308
366
|
} else {
|
|
309
367
|
res.send(result);
|
|
310
368
|
}
|
|
311
369
|
});
|
|
312
370
|
|
|
313
371
|
//route handler for the retrieve Bacnet server points function
|
|
314
|
-
RED.httpAdmin.get(
|
|
372
|
+
RED.httpAdmin.get("/bitpool-bacnet-data/getBacnetServerPoints", function (req, res) {
|
|
315
373
|
if (node.bacnetServerEnabled == true && node.bacnetClient) {
|
|
316
|
-
node.bacnetServer
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
374
|
+
node.bacnetServer
|
|
375
|
+
.getServerPoints()
|
|
376
|
+
.then(function (result) {
|
|
377
|
+
res.send(result);
|
|
378
|
+
})
|
|
379
|
+
.catch(function (error) {
|
|
380
|
+
res.send(error);
|
|
381
|
+
logOut("Error getting server points: ", error);
|
|
382
|
+
});
|
|
322
383
|
} else {
|
|
323
384
|
res.send([]);
|
|
324
385
|
}
|
|
@@ -443,6 +504,24 @@ module.exports = function (RED) {
|
|
|
443
504
|
}
|
|
444
505
|
});
|
|
445
506
|
|
|
507
|
+
//route handler for updatePoint
|
|
508
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/updatePoint", function (req, res) {
|
|
509
|
+
if (!node.bacnetClient) {
|
|
510
|
+
logOut("Issue with the bacnetClient while updating device points list: ", node.bacnetClient);
|
|
511
|
+
res.send(false);
|
|
512
|
+
} else {
|
|
513
|
+
node.bacnetClient
|
|
514
|
+
.updateIndividualPoint(req.body.d, req.body.k)
|
|
515
|
+
.then(function (result) {
|
|
516
|
+
res.send(result);
|
|
517
|
+
})
|
|
518
|
+
.catch(function (error) {
|
|
519
|
+
res.send(error);
|
|
520
|
+
logOut("Error updating device: ", error);
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
|
|
446
525
|
//route handler for setDeviceDisplayName
|
|
447
526
|
RED.httpAdmin.post("/bitpool-bacnet-data/setDeviceDisplayName", function (req, res) {
|
|
448
527
|
if (!node.bacnetClient) {
|
|
@@ -497,63 +576,90 @@ module.exports = function (RED) {
|
|
|
497
576
|
}
|
|
498
577
|
});
|
|
499
578
|
|
|
500
|
-
|
|
501
579
|
function bindEventListeners() {
|
|
502
580
|
// Value response event handler for READ commands
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
let useDeviceName = outputType.useDeviceName;
|
|
513
|
-
if (outputType.json && !outputType.mqtt && !outputType.pointJson) {
|
|
514
|
-
//json
|
|
515
|
-
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
516
|
-
//simpleWithStatus
|
|
517
|
-
sendSimpleWithStatus(values, readNodeName, true, useDeviceName);
|
|
518
|
-
} else if (objectPropertyType.fullObject && !objectPropertyType.simplePayload && !objectPropertyType.simpleWithStatus) {
|
|
519
|
-
//fullObject
|
|
520
|
-
sendJsonAsMqtt(values, readNodeName, useDeviceName);
|
|
521
|
-
} else if (objectPropertyType.simplePayload && !objectPropertyType.fullObject && !objectPropertyType.simpleWithStatus) {
|
|
522
|
-
//simplePayload
|
|
523
|
-
sendSimpleJson(values, readNodeName, useDeviceName);
|
|
581
|
+
try {
|
|
582
|
+
node.bacnetClient.on("values", (values, outputType, objectPropertyType, readNodeName, deviceIndex, devicesToRead) => {
|
|
583
|
+
if (typeof values !== "undefined" && Object.keys(values).length) {
|
|
584
|
+
let publishText = `Publishing ${readNodeName} ${deviceIndex} / ${devicesToRead} `;
|
|
585
|
+
node.status({ fill: "blue", shape: "dot", text: publishText });
|
|
586
|
+
if (deviceIndex == devicesToRead) {
|
|
587
|
+
setTimeout(() => {
|
|
588
|
+
node.status({});
|
|
589
|
+
}, 3000);
|
|
524
590
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
591
|
+
let useDeviceName = outputType.useDeviceName;
|
|
592
|
+
if (outputType.json && !outputType.mqtt && !outputType.pointJson) {
|
|
593
|
+
//json
|
|
594
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
595
|
+
//simpleWithStatus
|
|
596
|
+
sendSimpleWithStatus(values, readNodeName, true, useDeviceName);
|
|
597
|
+
} else if (
|
|
598
|
+
objectPropertyType.fullObject &&
|
|
599
|
+
!objectPropertyType.simplePayload &&
|
|
600
|
+
!objectPropertyType.simpleWithStatus
|
|
601
|
+
) {
|
|
602
|
+
//fullObject
|
|
603
|
+
sendJsonAsMqtt(values, readNodeName, useDeviceName);
|
|
604
|
+
} else if (
|
|
605
|
+
objectPropertyType.simplePayload &&
|
|
606
|
+
!objectPropertyType.fullObject &&
|
|
607
|
+
!objectPropertyType.simpleWithStatus
|
|
608
|
+
) {
|
|
609
|
+
//simplePayload
|
|
610
|
+
sendSimpleJson(values, readNodeName, useDeviceName);
|
|
611
|
+
}
|
|
612
|
+
} else if (outputType.mqtt && !outputType.json && !outputType.pointJson) {
|
|
613
|
+
//mqtt
|
|
614
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
615
|
+
//simpleWithStatus
|
|
616
|
+
sendSimpleWithStatus(values, readNodeName, false, useDeviceName);
|
|
617
|
+
} else if (
|
|
618
|
+
objectPropertyType.fullObject &&
|
|
619
|
+
!objectPropertyType.simplePayload &&
|
|
620
|
+
!objectPropertyType.simpleWithStatus
|
|
621
|
+
) {
|
|
622
|
+
//fullObject
|
|
623
|
+
sendAsMqtt(values, readNodeName, useDeviceName);
|
|
624
|
+
} else if (
|
|
625
|
+
objectPropertyType.simplePayload &&
|
|
626
|
+
!objectPropertyType.fullObject &&
|
|
627
|
+
!objectPropertyType.simpleWithStatus
|
|
628
|
+
) {
|
|
629
|
+
//simplePayload
|
|
630
|
+
sendSimpleMqtt(values, readNodeName, useDeviceName);
|
|
631
|
+
}
|
|
632
|
+
} else if (outputType.pointJson && !outputType.json && !outputType.mqtt) {
|
|
633
|
+
//pointJson
|
|
634
|
+
if (objectPropertyType.simpleWithStatus && !objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
635
|
+
//simpleWithStatus
|
|
636
|
+
sendSimpleWithStatus(values, readNodeName, false, useDeviceName);
|
|
637
|
+
} else if (
|
|
638
|
+
objectPropertyType.fullObject &&
|
|
639
|
+
!objectPropertyType.simplePayload &&
|
|
640
|
+
!objectPropertyType.simpleWithStatus
|
|
641
|
+
) {
|
|
642
|
+
//fullObject
|
|
643
|
+
sendIndividualMsgJson(values, readNodeName, useDeviceName);
|
|
644
|
+
} else if (
|
|
645
|
+
objectPropertyType.simplePayload &&
|
|
646
|
+
!objectPropertyType.fullObject &&
|
|
647
|
+
!objectPropertyType.simpleWithStatus
|
|
648
|
+
) {
|
|
649
|
+
//simplePayload
|
|
650
|
+
sendSimpleJsonPerPoint(values, readNodeName, useDeviceName);
|
|
651
|
+
}
|
|
548
652
|
}
|
|
549
653
|
}
|
|
550
|
-
}
|
|
551
|
-
});
|
|
654
|
+
});
|
|
552
655
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
656
|
+
// Who Is / Iam event handler
|
|
657
|
+
node.bacnetClient.on("deviceFound", (device) => {
|
|
658
|
+
if (node.toLogIam) node.warn(`BACnet device found: ${device.deviceId} - ${device.address}`);
|
|
659
|
+
});
|
|
660
|
+
} catch (e) {
|
|
661
|
+
console.log("Bacnet gateway BindListeners error: ", e);
|
|
662
|
+
}
|
|
557
663
|
}
|
|
558
664
|
|
|
559
665
|
function logOut(param1, param2) {
|
|
@@ -577,16 +683,12 @@ module.exports = function (RED) {
|
|
|
577
683
|
node.nodeName !== "undefined" &&
|
|
578
684
|
typeof node.nodeName == "string"
|
|
579
685
|
) {
|
|
580
|
-
if (readNodeName !==
|
|
581
|
-
readNodeName !== null &&
|
|
582
|
-
readNodeName !== undefined
|
|
583
|
-
) {
|
|
686
|
+
if (readNodeName !== "" && readNodeName !== null && readNodeName !== undefined) {
|
|
584
687
|
if (useDeviceName) {
|
|
585
688
|
topic = `${node.nodeName}/${readNodeName}/${device}`;
|
|
586
689
|
} else {
|
|
587
690
|
topic = `${node.nodeName}/${readNodeName}`;
|
|
588
691
|
}
|
|
589
|
-
|
|
590
692
|
} else {
|
|
591
693
|
if (useDeviceName) {
|
|
592
694
|
topic = `${node.nodeName}/${device}`;
|
|
@@ -595,16 +697,12 @@ module.exports = function (RED) {
|
|
|
595
697
|
}
|
|
596
698
|
}
|
|
597
699
|
} else {
|
|
598
|
-
if (readNodeName !==
|
|
599
|
-
readNodeName !== null &&
|
|
600
|
-
readNodeName !== undefined
|
|
601
|
-
) {
|
|
700
|
+
if (readNodeName !== "" && readNodeName !== null && readNodeName !== undefined) {
|
|
602
701
|
if (useDeviceName) {
|
|
603
702
|
topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}`;
|
|
604
703
|
} else {
|
|
605
704
|
topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}`;
|
|
606
705
|
}
|
|
607
|
-
|
|
608
706
|
} else {
|
|
609
707
|
if (useDeviceName) {
|
|
610
708
|
topic = `BITPOOL_BACNET_GATEWAY/${device}`;
|
|
@@ -652,7 +750,6 @@ module.exports = function (RED) {
|
|
|
652
750
|
}
|
|
653
751
|
|
|
654
752
|
return topic;
|
|
655
|
-
|
|
656
753
|
}
|
|
657
754
|
|
|
658
755
|
sendSimpleWithStatus = function (values, readNodeName, isJson, useDeviceName) {
|
|
@@ -671,7 +768,7 @@ module.exports = function (RED) {
|
|
|
671
768
|
let payload = {
|
|
672
769
|
presentValue: points[point]["presentValue"],
|
|
673
770
|
timestamp: points[point]["timestamp"],
|
|
674
|
-
status: points[point]["status"]
|
|
771
|
+
status: points[point]["status"],
|
|
675
772
|
};
|
|
676
773
|
|
|
677
774
|
if (isJson) {
|
|
@@ -697,7 +794,7 @@ module.exports = function (RED) {
|
|
|
697
794
|
}
|
|
698
795
|
}
|
|
699
796
|
});
|
|
700
|
-
}
|
|
797
|
+
};
|
|
701
798
|
|
|
702
799
|
sendSimpleMqtt = function (values, readNodeName, useDeviceName) {
|
|
703
800
|
let devices = Object.keys(values);
|
|
@@ -817,7 +914,7 @@ module.exports = function (RED) {
|
|
|
817
914
|
}
|
|
818
915
|
});
|
|
819
916
|
}
|
|
820
|
-
}
|
|
917
|
+
};
|
|
821
918
|
|
|
822
919
|
sendSimpleJsonPerPoint = function (values, readNodeName, useDeviceName) {
|
|
823
920
|
let devices = Object.keys(values);
|
|
@@ -832,7 +929,7 @@ module.exports = function (RED) {
|
|
|
832
929
|
|
|
833
930
|
msgg.topic = topic;
|
|
834
931
|
let payload = {
|
|
835
|
-
presentValue: points[point]["presentValue"]
|
|
932
|
+
presentValue: points[point]["presentValue"],
|
|
836
933
|
};
|
|
837
934
|
msgg.payload = payload;
|
|
838
935
|
node.send(msgg);
|
|
@@ -841,7 +938,7 @@ module.exports = function (RED) {
|
|
|
841
938
|
}
|
|
842
939
|
}
|
|
843
940
|
});
|
|
844
|
-
}
|
|
941
|
+
};
|
|
845
942
|
|
|
846
943
|
function getPointName(object, pointName) {
|
|
847
944
|
if (object.displayName) {
|
|
@@ -849,7 +946,6 @@ module.exports = function (RED) {
|
|
|
849
946
|
}
|
|
850
947
|
return pointName;
|
|
851
948
|
}
|
|
852
|
-
|
|
853
949
|
}
|
|
854
950
|
RED.nodes.registerType("Bacnet-Gateway", BitpoolBacnetGatewayDevice);
|
|
855
951
|
};
|