@halsystems/red-bacnet 2.0.3 → 2.1.0-alpha.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.1.0-alpha.0]
|
|
4
|
+
### Added
|
|
5
|
+
- BACnet client now listening to both `interface` and `broadcastAddress`
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- `discover_devices` to drop devices that are not within the low and high limit
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fixed unable to discover devices from broadcast when `interface` is not set to `0.0.0.0`
|
|
12
|
+
|
|
13
|
+
|
|
3
14
|
## [2.0.3]
|
|
4
15
|
### Fixed
|
|
5
16
|
- Added unique job id to same node type to avoid same time triggered nodes job being coalesced
|
|
@@ -165,7 +165,12 @@ module.exports = {
|
|
|
165
165
|
const adr = device.adr
|
|
166
166
|
const net = device.net
|
|
167
167
|
|
|
168
|
+
// Check for duplicate
|
|
168
169
|
if (this.knownDevices.has(deviceId)) return;
|
|
170
|
+
|
|
171
|
+
// Drop device if deviceId is not within the low and high limit
|
|
172
|
+
if (deviceId < this.lowLimit || deviceId > this.highLimit) return;
|
|
173
|
+
|
|
169
174
|
this.discoverList.push({
|
|
170
175
|
deviceId: deviceId,
|
|
171
176
|
address: address,
|
|
@@ -59,6 +59,13 @@ class Client extends events_1.EventEmitter {
|
|
|
59
59
|
// Setup code
|
|
60
60
|
this._transport.on('message', this._receiveData.bind(this));
|
|
61
61
|
this._transport.on('error', this._receiveError.bind(this));
|
|
62
|
+
|
|
63
|
+
// Add a default error handler to prevent unhandled error events
|
|
64
|
+
// This will be overridden if the user adds their own error listener
|
|
65
|
+
this.on('error', (err) => {
|
|
66
|
+
debug('Unhandled error event:', err);
|
|
67
|
+
});
|
|
68
|
+
|
|
62
69
|
this._transport.open();
|
|
63
70
|
}
|
|
64
71
|
// Helper utils
|
|
@@ -1,62 +1,114 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Transport = void 0;
|
|
4
4
|
const dgram_1 = require("dgram");
|
|
5
5
|
const events_1 = require("events");
|
|
6
6
|
const DEFAULT_BACNET_PORT = 47808;
|
|
7
|
+
const GLOBAL_BROADCAST_ADDRESS = "255.255.255.255";
|
|
8
|
+
const UDP_TYPE = "udp4";
|
|
9
|
+
|
|
7
10
|
class Transport extends events_1.EventEmitter {
|
|
8
11
|
constructor(settings) {
|
|
9
12
|
super();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this._server = (0, dgram_1.createSocket)({ type: 'udp4', reuseAddr: true });
|
|
14
|
-
this._server.on('message', (msg, rinfo) => {
|
|
15
|
-
// NOTE HAL modified
|
|
16
|
-
const port = rinfo.port || DEFAULT_BACNET_PORT;
|
|
17
|
-
// this.emit('message', msg, `${rinfo.address}:${port}`);
|
|
18
|
-
if (port === DEFAULT_BACNET_PORT)
|
|
19
|
-
this.emit('message', msg, rinfo.address);
|
|
20
|
-
else
|
|
21
|
-
this.emit('message', msg, `${rinfo.address}:${rinfo.port || DEFAULT_BACNET_PORT}`);
|
|
22
|
-
});
|
|
23
|
-
this._server.on('error', (err) => this.emit('message', err));
|
|
13
|
+
this._settings = settings;
|
|
14
|
+
this._server = null;
|
|
15
|
+
this._broadcastServer = null;
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
this._server = (0, dgram_1.createSocket)({
|
|
18
|
+
type: UDP_TYPE,
|
|
19
|
+
reuseAddr: true,
|
|
20
|
+
});
|
|
21
|
+
this._setupSocket(this._server);
|
|
22
|
+
|
|
23
|
+
if (
|
|
24
|
+
this._settings.broadcastAddress &&
|
|
25
|
+
this._settings.broadcastAddress !== GLOBAL_BROADCAST_ADDRESS &&
|
|
26
|
+
this._settings.broadcastAddress !== this._settings.interface
|
|
27
|
+
) {
|
|
28
|
+
this._broadcastServer = (0, dgram_1.createSocket)({
|
|
29
|
+
type: UDP_TYPE,
|
|
30
|
+
reuseAddr: true,
|
|
31
|
+
});
|
|
32
|
+
this._setupSocket(this._broadcastServer);
|
|
27
33
|
}
|
|
28
34
|
}
|
|
35
|
+
|
|
36
|
+
_setupSocket(socket) {
|
|
37
|
+
socket.on("message", (msg, rinfo) => {
|
|
38
|
+
const port = rinfo.port || DEFAULT_BACNET_PORT;
|
|
39
|
+
if (port === DEFAULT_BACNET_PORT) {
|
|
40
|
+
this.emit("message", msg, rinfo.address);
|
|
41
|
+
} else {
|
|
42
|
+
this.emit("message", msg, `${rinfo.address}:${port}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
socket.on("error", (err) => this.emit("error", err));
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
getBroadcastAddress() {
|
|
30
49
|
return this._settings.broadcastAddress;
|
|
31
50
|
}
|
|
51
|
+
|
|
32
52
|
getMaxPayload() {
|
|
33
53
|
return 1482;
|
|
34
54
|
}
|
|
55
|
+
|
|
35
56
|
send(buffer, offset, receiver) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
buffer.copy(dataToSend, 0, 0, offset);
|
|
44
|
-
this._lastSendMessages[messageKey] = dataToSend;
|
|
45
|
-
setTimeout(() => {
|
|
46
|
-
delete this._lastSendMessages[messageKey];
|
|
47
|
-
}, 10000); // delete after 10s, hopefully all cases are handled by that
|
|
57
|
+
const target = receiver || this.getBroadcastAddress();
|
|
58
|
+
if (!target) {
|
|
59
|
+
this.emit(
|
|
60
|
+
"error",
|
|
61
|
+
new Error("No receiver specified and no broadcast address configured"),
|
|
62
|
+
);
|
|
63
|
+
return;
|
|
48
64
|
}
|
|
49
65
|
|
|
50
|
-
const [address, port] =
|
|
51
|
-
this._server.send(
|
|
66
|
+
const [address, port] = target.split(":");
|
|
67
|
+
this._server.send(
|
|
68
|
+
buffer,
|
|
69
|
+
0,
|
|
70
|
+
offset,
|
|
71
|
+
port || this._settings.port || DEFAULT_BACNET_PORT,
|
|
72
|
+
address,
|
|
73
|
+
(err) => {
|
|
74
|
+
if (err) {
|
|
75
|
+
this.emit("error", err);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
);
|
|
52
79
|
}
|
|
80
|
+
|
|
53
81
|
open() {
|
|
82
|
+
this._server.on("error", (err) => this.emit("error", err));
|
|
54
83
|
this._server.bind(this._settings.port, this._settings.interface, () => {
|
|
55
84
|
this._server.setBroadcast(true);
|
|
56
85
|
});
|
|
86
|
+
|
|
87
|
+
if (this._broadcastServer) {
|
|
88
|
+
this._broadcastServer.on("error", (err) => {
|
|
89
|
+
this.emit("error", err);
|
|
90
|
+
this._broadcastServer.close();
|
|
91
|
+
this._broadcastServer = null;
|
|
92
|
+
});
|
|
93
|
+
this._broadcastServer.bind(
|
|
94
|
+
this._settings.port,
|
|
95
|
+
this._settings.broadcastAddress,
|
|
96
|
+
() => {
|
|
97
|
+
this._broadcastServer.setBroadcast(true);
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
57
101
|
}
|
|
102
|
+
|
|
58
103
|
close() {
|
|
59
|
-
this._server
|
|
104
|
+
if (this._server) {
|
|
105
|
+
this._server.removeAllListeners();
|
|
106
|
+
this._server.close();
|
|
107
|
+
}
|
|
108
|
+
if (this._broadcastServer) {
|
|
109
|
+
this._broadcastServer.removeAllListeners();
|
|
110
|
+
this._broadcastServer.close();
|
|
111
|
+
}
|
|
60
112
|
}
|
|
61
113
|
}
|
|
62
114
|
exports.Transport = Transport;
|