@bitpoolos/edge-bacnet 1.6.7 → 1.6.9

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 (48) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/bacnet_client.js +181 -28
  3. package/bacnet_device.js +16 -15
  4. package/bacnet_gateway.html +82 -0
  5. package/bacnet_gateway.js +3 -1
  6. package/bacnet_write.html +2 -1
  7. package/common.js +8 -1
  8. package/package.json +1 -1
  9. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -41
  10. package/resources/node-bacstack-ts/dist/index.js +0 -3
  11. package/resources/node-bacstack-ts/dist/lib/apdu.js +0 -193
  12. package/resources/node-bacstack-ts/dist/lib/asn1.js +0 -1671
  13. package/resources/node-bacstack-ts/dist/lib/bvlc.js +0 -47
  14. package/resources/node-bacstack-ts/dist/lib/client.js +0 -1553
  15. package/resources/node-bacstack-ts/dist/lib/enum.js +0 -2114
  16. package/resources/node-bacstack-ts/dist/lib/npdu.js +0 -112
  17. package/resources/node-bacstack-ts/dist/lib/services/add-list-element.js +0 -58
  18. package/resources/node-bacstack-ts/dist/lib/services/alarm-acknowledge.js +0 -93
  19. package/resources/node-bacstack-ts/dist/lib/services/alarm-summary.js +0 -42
  20. package/resources/node-bacstack-ts/dist/lib/services/atomic-read-file.js +0 -157
  21. package/resources/node-bacstack-ts/dist/lib/services/atomic-write-file.js +0 -136
  22. package/resources/node-bacstack-ts/dist/lib/services/cov-notify.js +0 -119
  23. package/resources/node-bacstack-ts/dist/lib/services/create-object.js +0 -104
  24. package/resources/node-bacstack-ts/dist/lib/services/delete-object.js +0 -21
  25. package/resources/node-bacstack-ts/dist/lib/services/device-communication-control.js +0 -46
  26. package/resources/node-bacstack-ts/dist/lib/services/error.js +0 -27
  27. package/resources/node-bacstack-ts/dist/lib/services/event-information.js +0 -100
  28. package/resources/node-bacstack-ts/dist/lib/services/event-notify-data.js +0 -219
  29. package/resources/node-bacstack-ts/dist/lib/services/get-enrollment-summary.js +0 -172
  30. package/resources/node-bacstack-ts/dist/lib/services/get-event-information.js +0 -135
  31. package/resources/node-bacstack-ts/dist/lib/services/i-am-broadcast.js +0 -59
  32. package/resources/node-bacstack-ts/dist/lib/services/i-have-broadcast.js +0 -34
  33. package/resources/node-bacstack-ts/dist/lib/services/index.js +0 -32
  34. package/resources/node-bacstack-ts/dist/lib/services/life-safety-operation.js +0 -40
  35. package/resources/node-bacstack-ts/dist/lib/services/private-transfer.js +0 -43
  36. package/resources/node-bacstack-ts/dist/lib/services/read-property-multiple.js +0 -44
  37. package/resources/node-bacstack-ts/dist/lib/services/read-property.js +0 -122
  38. package/resources/node-bacstack-ts/dist/lib/services/read-range.js +0 -201
  39. package/resources/node-bacstack-ts/dist/lib/services/reinitialize-device.js +0 -35
  40. package/resources/node-bacstack-ts/dist/lib/services/subscribe-cov.js +0 -55
  41. package/resources/node-bacstack-ts/dist/lib/services/subscribe-property.js +0 -93
  42. package/resources/node-bacstack-ts/dist/lib/services/time-sync.js +0 -31
  43. package/resources/node-bacstack-ts/dist/lib/services/who-has.js +0 -56
  44. package/resources/node-bacstack-ts/dist/lib/services/who-is.js +0 -45
  45. package/resources/node-bacstack-ts/dist/lib/services/write-property-multiple.js +0 -105
  46. package/resources/node-bacstack-ts/dist/lib/services/write-property.js +0 -90
  47. package/resources/node-bacstack-ts/dist/lib/transport.js +0 -86
  48. package/resources/node-bacstack-ts/dist/lib/types.js +0 -2
@@ -1,1553 +0,0 @@
1
- 'use strict';
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Client = void 0;
4
- // Util Modules
5
- const events_1 = require("events");
6
- const debug_1 = require("debug");
7
- const debug = (0, debug_1.default)('bacstack');
8
- // Local Modules
9
- const transport_1 = require("./transport");
10
- const baServices = require("./services");
11
- const baAsn1 = require("./asn1");
12
- const baApdu = require("./apdu");
13
- const baNpdu = require("./npdu");
14
- const baBvlc = require("./bvlc");
15
- const baEnum = require("./enum");
16
- const DEFAULT_HOP_COUNT = 0xFF;
17
- const BVLC_HEADER_LENGTH = 4;
18
- /**
19
- * To be able to communicate to BACNET devices, you have to initialize a new bacstack instance.
20
- * @class bacstack
21
- * @param {object=} this._settings - The options object used for parameterizing the bacstack.
22
- * @param {number=} [options.port=47808] - BACNET communication port for listening and sending.
23
- * @param {string=} options.interface - Specific BACNET communication interface if different from primary one.
24
- * @param {string=} [options.broadcastAddress=255.255.255.255] - The address used for broadcast messages.
25
- * @param {number=} [options.apduTimeout=3000] - The timeout in milliseconds until a transaction should be interpreted as error.
26
- * @example
27
- * const bacnet = require('bacstack');
28
- *
29
- * const client = new bacnet({
30
- * port: 47809, // Use BAC1 as communication port
31
- * interface: '192.168.251.10', // Listen on a specific interface
32
- * broadcastAddress: '192.168.251.255', // Use the subnet broadcast address
33
- * apduTimeout: 6000 // Wait twice as long for response
34
- * });
35
- */
36
- class Client extends events_1.EventEmitter {
37
- constructor(options) {
38
- super();
39
- this._invokeCounter = 1;
40
- this._invokeStore = {};
41
- this._lastSequenceNumber = 0;
42
- this._segmentStore = [];
43
- options = options || {};
44
-
45
- this.portRangeMatrix = options.portRangeMatrix;
46
-
47
- this._settings = {
48
- port: options.port || 47808,
49
- portRangeMatrix: this.portRangeMatrix || [47808],
50
- interface: options.interface,
51
- transport: options.transport,
52
- broadcastAddress: options.broadcastAddress || '255.255.255.255',
53
- apduTimeout: options.apduTimeout || 3000
54
- };
55
-
56
- this._transport = this._settings.transport || new transport_1.Transport({
57
- port: this._settings.port,
58
- interface: this._settings.interface,
59
- broadcastAddress: this._settings.broadcastAddress,
60
- portRangeMatrix: this._settings.portRangeMatrix
61
- });
62
-
63
- // Setup code
64
- this._transport.on('message', this._receiveData.bind(this));
65
- this._transport.on('error', this._receiveError.bind(this));
66
- this._transport.open();
67
- }
68
- // Helper utils
69
- _getInvokeId() {
70
- // Try up to 256 times to find an unused invoke ID
71
- for (let attempts = 0; attempts < 256; attempts++) {
72
- const id = this._invokeCounter++;
73
- if (id >= 256) this._invokeCounter = 1;
74
-
75
- const invokeId = id - 1;
76
-
77
- // If this invoke ID is not currently in use, return it
78
- if (!this._invokeStore[invokeId]) {
79
- return invokeId;
80
- }
81
- }
82
-
83
- // Edge case: if all 256 invoke IDs are in use, fall back to original behavior
84
- // This prevents infinite loops while maintaining backwards compatibility
85
- const id = this._invokeCounter++;
86
- if (id >= 256) this._invokeCounter = 1;
87
- return id - 1;
88
- }
89
- _invokeCallback(id, err, result) {
90
- const callback = this._invokeStore[id];
91
- if (callback)
92
- return callback(err, result);
93
- debug('InvokeId ', id, ' not found -> drop package');
94
- }
95
- _addCallback(id, callback) {
96
- const timeout = setTimeout(() => {
97
- delete this._invokeStore[id];
98
- callback(new Error('ERR_TIMEOUT'));
99
- }, this._settings.apduTimeout);
100
- this._invokeStore[id] = (err, data) => {
101
- clearTimeout(timeout);
102
- delete this._invokeStore[id];
103
- callback(err, data);
104
- };
105
- }
106
- _getBuffer() {
107
- return {
108
- buffer: Buffer.alloc(this._transport.getMaxPayload()),
109
- offset: BVLC_HEADER_LENGTH
110
- };
111
- }
112
- // Service Handlers
113
- _processError(invokeId, buffer, offset, length) {
114
- try {
115
- const result = baServices.error.decode(buffer, offset);
116
- if (!result)
117
- return debug('Couldn`t decode Error');
118
- this._invokeCallback(invokeId, new Error('BacnetError - Class:' + result.class + ' - Code:' + result.code));
119
- } catch (e) {
120
- }
121
- }
122
- _processAbort(invokeId, reason) {
123
- this._invokeCallback(invokeId, new Error('BacnetAbort - Reason:' + reason));
124
- }
125
- _segmentAckResponse(receiver, port, negative, server, originalInvokeId, sequencenumber, actualWindowSize) {
126
- const buffer = this._getBuffer();
127
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
128
- baApdu.encodeSegmentAck(buffer, baEnum.PduTypes.SEGMENT_ACK | (negative ? baEnum.PduSegAckBits.NEGATIVE_ACK : 0) | (server ? baEnum.PduSegAckBits.SERVER : 0), originalInvokeId, sequencenumber, actualWindowSize);
129
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
130
- var sendAddress = typeof (receiver) != 'string' ? receiver.ip : receiver;
131
- this.sendBvlc(sendAddress, port, buffer);
132
- }
133
- _performDefaultSegmentHandling(sender, adr, type, service, invokeId, maxSegments, maxApdu, sequencenumber, first, moreFollows, buffer, offset, length, port) {
134
- if (first) {
135
- this._segmentStore = [];
136
- type &= ~baEnum.PduConReqBits.SEGMENTED_MESSAGE;
137
- let apduHeaderLen = 3;
138
- if ((type & baEnum.PDU_TYPE_MASK) === baEnum.PduTypes.CONFIRMED_REQUEST) {
139
- apduHeaderLen = 4;
140
- }
141
- const apdubuffer = this._getBuffer();
142
- apdubuffer.offset = 0;
143
- buffer.copy(apdubuffer.buffer, apduHeaderLen, offset, offset + length);
144
- if ((type & baEnum.PDU_TYPE_MASK) === baEnum.PduTypes.CONFIRMED_REQUEST) {
145
- baApdu.encodeConfirmedServiceRequest(apdubuffer, type, service, maxSegments, maxApdu, invokeId, 0, 0);
146
- }
147
- else {
148
- baApdu.encodeComplexAck(apdubuffer, type, service, invokeId, 0, 0);
149
- }
150
- this._segmentStore.push(apdubuffer.buffer.slice(0, length + apduHeaderLen));
151
- }
152
- else {
153
- this._segmentStore.push(buffer.slice(offset, offset + length));
154
- }
155
- if (!moreFollows) {
156
- const apduBuffer = Buffer.concat(this._segmentStore);
157
- this._segmentStore = [];
158
- type &= ~baEnum.PduConReqBits.SEGMENTED_MESSAGE;
159
- this._handlePdu(adr, type, apduBuffer, 0, apduBuffer.length, port);
160
- }
161
- }
162
- _handleSequenceTimeout(invokeId) {
163
- if (this._sequenceTimeout) {
164
- clearInterval(this._sequenceTimeout);
165
- }
166
- this._sequenceTimeout = setTimeout(() => { this._lastSequenceNumber = 0 }, this._settings.apduTimeout);
167
- }
168
-
169
- _processSegment(receiver, type, service, invokeId, maxSegments, maxApdu, server, sequencenumber, proposedWindowNumber, buffer, offset, length, port) {
170
- let first = false;
171
- if (sequencenumber === 0 && this._lastSequenceNumber === 0) {
172
- first = true;
173
- } else {
174
- if (sequencenumber !== this._lastSequenceNumber + 1) {
175
- return this._segmentAckResponse(receiver, port, true, server, invokeId, this._lastSequenceNumber, proposedWindowNumber);
176
- }
177
- }
178
- this._lastSequenceNumber = sequencenumber;
179
- this._handleSequenceTimeout();
180
- const moreFollows = type & baEnum.PduConReqBits.MORE_FOLLOWS;
181
- if (!moreFollows) {
182
- this._lastSequenceNumber = 0;
183
- }
184
- if ((sequencenumber % proposedWindowNumber) === 0 || !moreFollows) {
185
- this._segmentAckResponse(receiver, port, false, server, invokeId, sequencenumber, proposedWindowNumber);
186
- }
187
- this._performDefaultSegmentHandling(this, receiver, type, service, invokeId, maxSegments, maxApdu, sequencenumber, first, moreFollows, buffer, offset, length, port);
188
- }
189
-
190
- _processConfirmedServiceRequest(address, type, service, maxSegments, maxApdu, invokeId, buffer, offset, length, srcAddress, destAddress) {
191
- let result;
192
- debug('Handle this._processConfirmedServiceRequest');
193
- if (service === baEnum.ConfirmedServiceChoice.READ_PROPERTY) {
194
- result = baServices.readProperty.decode(buffer, offset, length);
195
- if (!result) return debug('Received invalid readProperty message');
196
- this.emit('readProperty', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress, destAddress: destAddress });
197
- } else if (service === baEnum.ConfirmedServiceChoice.WRITE_PROPERTY) {
198
- result = baServices.writeProperty.decode(buffer, offset, length);
199
- if (!result) return debug('Received invalid writeProperty message');
200
- this.emit('writeProperty', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress, destAddress: destAddress });
201
- } else if (service === baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE) {
202
- result = baServices.readPropertyMultiple.decode(buffer, offset, length);
203
- if (!result) return debug('Received invalid readPropertyMultiple message');
204
- this.emit('readPropertyMultiple', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress, destAddress: destAddress });
205
- } else if (service === baEnum.ConfirmedServiceChoice.WRITE_PROPERTY_MULTIPLE) {
206
- result = baServices.writePropertyMultiple.decode(buffer, offset, length);
207
- if (!result) return debug('Received invalid writePropertyMultiple message');
208
- this.emit('writePropertyMultiple', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress, destAddress: destAddress });
209
- } else if (service === baEnum.ConfirmedServiceChoice.CONFIRMED_COV_NOTIFICATION) {
210
- result = baServices.covNotify.decode(buffer, offset, length);
211
- if (!result) return debug('Received invalid covNotify message');
212
- this.emit('covNotify', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
213
- } else if (service === baEnum.ConfirmedServiceChoice.ATOMIC_WRITE_FILE) {
214
- result = baServices.atomicWriteFile.decode(buffer, offset, length);
215
- if (!result) return debug('Received invalid atomicWriteFile message');
216
- this.emit('atomicWriteFile', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
217
- } else if (service === baEnum.ConfirmedServiceChoice.ATOMIC_READ_FILE) {
218
- result = baServices.atomicReadFile.decode(buffer, offset, length);
219
- if (!result) return debug('Received invalid atomicReadFile message');
220
- this.emit('atomicReadFile', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
221
- } else if (service === baEnum.ConfirmedServiceChoice.SUBSCRIBE_COV) {
222
- result = baServices.subscribeCov.decode(buffer, offset, length);
223
- if (!result) return debug('Received invalid subscribeCOV message');
224
- this.emit('subscribeCOV', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
225
- } else if (service === baEnum.ConfirmedServiceChoice.SUBSCRIBE_COV_PROPERTY) {
226
- result = baServices.subscribeProperty.decode(buffer, offset, length);
227
- if (!result) return debug('Received invalid subscribeProperty message');
228
- this.emit('subscribeProperty', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
229
- } else if (service === baEnum.ConfirmedServiceChoice.DEVICE_COMMUNICATION_CONTROL) {
230
- result = baServices.deviceCommunicationControl.decode(buffer, offset, length);
231
- if (!result) return debug('Received invalid deviceCommunicationControl message');
232
- this.emit('deviceCommunicationControl', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
233
- } else if (service === baEnum.ConfirmedServiceChoice.REINITIALIZE_DEVICE) {
234
- result = baServices.reinitializeDevice.decode(buffer, offset, length);
235
- if (!result) return debug('Received invalid reinitializeDevice message');
236
- this.emit('reinitializeDevice', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
237
- } else if (service === baEnum.ConfirmedServiceChoice.CONFIRMED_EVENT_NOTIFICATION) {
238
- result = baServices.eventNotifyData.decode(buffer, offset, length);
239
- if (!result) return debug('Received invalid eventNotifyData message');
240
- this.emit('eventNotifyData', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
241
- } else if (service === baEnum.ConfirmedServiceChoice.READ_RANGE) {
242
- result = baServices.readRange.decode(buffer, offset, length);
243
- if (!result) return debug('Received invalid readRange message');
244
- this.emit('readRange', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
245
- } else if (service === baEnum.ConfirmedServiceChoice.CREATE_OBJECT) {
246
- result = baServices.createObject.decode(buffer, offset, length);
247
- if (!result) return debug('Received invalid createObject message');
248
- this.emit('createObject', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
249
- } else if (service === baEnum.ConfirmedServiceChoice.DELETE_OBJECT) {
250
- result = baServices.deleteObject.decode(buffer, offset, length);
251
- if (!result) return debug('Received invalid deleteObject message');
252
- this.emit('deleteObject', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
253
- } else if (service === baEnum.ConfirmedServiceChoice.ACKNOWLEDGE_ALARM) {
254
- try {
255
- result = baServices.alarmAcknowledge.decode(buffer, offset, length);
256
- if (!result) return debug('Received invalid alarmAcknowledge message');
257
- this.emit('alarmAcknowledge', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
258
- } catch (e) {
259
- //console.log("Error in alarmAcknowledge: ", e);
260
- }
261
- } else if (service === baEnum.ConfirmedServiceChoice.GET_ALARM_SUMMARY) {
262
- this.emit('getAlarmSummary', { address: address, invokeId: invokeId });
263
- } else if (service === baEnum.ConfirmedServiceChoice.GET_ENROLLMENT_SUMMARY) {
264
- result = baServices.getEnrollmentSummary.decode(buffer, offset, length);
265
- if (!result) return debug('Received invalid getEntrollmentSummary message');
266
- this.emit('getEntrollmentSummary', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
267
- } else if (service === baEnum.ConfirmedServiceChoice.GET_EVENT_INFORMATION) {
268
- result = baServices.getEventInformation.decode(buffer, offset, length);
269
- if (!result) return debug('Received invalid getEventInformation message');
270
- this.emit('getEventInformation', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
271
- } else if (service === baEnum.ConfirmedServiceChoice.LIFE_SAFETY_OPERATION) {
272
- result = baServices.lifeSafetyOperation.decode(buffer, offset, length);
273
- if (!result) return debug('Received invalid lifeSafetyOperation message');
274
- this.emit('lifeSafetyOperation', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
275
- } else if (service === baEnum.ConfirmedServiceChoice.ADD_LIST_ELEMENT) {
276
- result = baServices.addListElement.decode(buffer, offset, length);
277
- if (!result) return debug('Received invalid addListElement message');
278
- this.emit('addListElement', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
279
- } else if (service === baEnum.ConfirmedServiceChoice.REMOVE_LIST_ELEMENT) {
280
- result = baServices.addListElement.decode(buffer, offset, length);
281
- if (!result) return debug('Received invalid removeListElement message');
282
- this.emit('removeListElement', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
283
- } else if (service === baEnum.ConfirmedServiceChoice.CONFIRMED_PRIVATE_TRANSFER) {
284
- result = baServices.privateTransfer.decode(buffer, offset, length);
285
- if (!result) return debug('Received invalid privateTransfer message');
286
- this.emit('privateTransfer', { address: address, invokeId: invokeId, request: result, srcAddress: srcAddress });
287
- } else {
288
- debug('Received unsupported confirmed service request');
289
- }
290
- }
291
-
292
- _processUnconfirmedServiceRequest(address, type, service, buffer, offset, length, addressObject, port) {
293
- let result;
294
- debug('Handle this._processUnconfirmedServiceRequest');
295
- if (service === baEnum.UnconfirmedServiceChoice.I_AM) {
296
- result = baServices.iAmBroadcast.decode(buffer, offset);
297
- if (!result) return debug('Received invalid iAm message');
298
-
299
- /**
300
- * The iAm event represents the response to a whoIs request to detect all devices in a BACNET network.
301
- * @event bacstack.iAm
302
- * @param {object} device - An object representing the detected device.
303
- * @param {string} device.address - The IP address of the detected device.
304
- * @param {number} device.deviceId - The BACNET device-id of the detected device.
305
- * @param {number} device.maxApdu - The max APDU size the detected device is supporting.
306
- * @param {number} device.segmentation - The type of segmentation the detected device is supporting.
307
- * @param {number} device.vendorId - The BACNET vendor-id of the detected device.
308
- * @example
309
- * const bacnet = require('bacstack');
310
- * const client = new bacnet();
311
- *
312
- * client.on('iAm', (device) => {
313
- * console.log('address: ', device.address, ' - deviceId: ', device.deviceId, ' - maxApdu: ', device.maxApdu, ' - segmentation: ', device.segmentation, ' - vendorId: ', device.vendorId);
314
- * });
315
- */
316
-
317
- var net = typeof (addressObject) == 'object' ? addressObject.net : undefined;
318
- var adr = typeof (addressObject) == 'object' ? addressObject.adr : undefined;
319
- this.emit('iAm', { address: address, port: port, deviceId: result.deviceId, maxApdu: result.maxApdu, segmentation: result.segmentation, vendorId: result.vendorId, 'net': net, 'adr': adr });
320
- } else if (service === baEnum.UnconfirmedServiceChoice.WHO_IS) {
321
- result = baServices.whoIs.decode(buffer, offset, length);
322
- if (!result) return debug('Received invalid WhoIs message');
323
-
324
- /**
325
- * The whoIs event represents the request for an IAm reponse to detect all devices in a BACNET network.
326
- * @event bacstack.whoIs
327
- * @param {object} request - An object representing the received request.
328
- * @param {string} request.address - The IP address of the device sending the request.
329
- * @param {number=} request.lowLimit - The lower limit of the BACNET device-id.
330
- * @param {number=} request.highLimit - The higher limit of the BACNET device-id.
331
- * @example
332
- * const bacnet = require('bacstack');
333
- * const client = new bacnet();
334
- *
335
- * client.on('whoIs', (request) => {
336
- * console.log('address: ', device.address, ' - lowLimit: ', device.lowLimit, ' - highLimit: ', device.highLimit);
337
- * });
338
- */
339
- this.emit('whoIs', { address: address, lowLimit: result.lowLimit, highLimit: result.highLimit });
340
- } else if (service === baEnum.UnconfirmedServiceChoice.WHO_HAS) {
341
- result = baServices.whoHas.decode(buffer, offset, length);
342
- if (!result) return debug('Received invalid WhoHas message');
343
- this.emit('whoHas', { address: address, lowLimit: result.lowLimit, highLimit: result.highLimit, objectId: result.objectId, objectName: result.objectName });
344
- } else if (service === baEnum.UnconfirmedServiceChoice.UNCONFIRMED_COV_NOTIFICATION) {
345
- result = baServices.covNotify.decode(buffer, offset, length);
346
- if (!result) return debug('Received invalid covNotifyUnconfirmed message');
347
- this.emit('covNotifyUnconfirmed', { address: address, request: result });
348
- } else if (service === baEnum.UnconfirmedServiceChoice.TIME_SYNCHRONIZATION) {
349
- result = baServices.timeSync.decode(buffer, offset, length);
350
- if (!result) return debug('Received invalid TimeSync message');
351
-
352
- /**
353
- * The timeSync event represents the request to synchronize the local time to the received time.
354
- * @event bacstack.timeSync
355
- * @param {object} request - An object representing the received request.
356
- * @param {string} request.address - The IP address of the device sending the request.
357
- * @param {date} request.dateTime - The time to be synchronized to.
358
- * @example
359
- * const bacnet = require('bacstack');
360
- * const client = new bacnet();
361
- *
362
- * client.on('timeSync', (request) => {
363
- * console.log('address: ', device.address, ' - dateTime: ', device.dateTime);
364
- * });
365
- */
366
- this.emit('timeSync', { address: address, dateTime: result.dateTime });
367
- } else if (service === baEnum.UnconfirmedServiceChoice.UTC_TIME_SYNCHRONIZATION) {
368
- result = baServices.timeSync.decode(buffer, offset, length);
369
- if (!result) return debug('Received invalid TimeSyncUTC message');
370
-
371
- /**
372
- * The timeSyncUTC event represents the request to synchronize the local time to the received UTC time.
373
- * @event bacstack.timeSyncUTC
374
- * @param {object} request - An object representing the received request.
375
- * @param {string} request.address - The IP address of the device sending the request.
376
- * @param {date} request.dateTime - The time to be synchronized to.
377
- * @example
378
- * const bacnet = require('bacstack');
379
- * const client = new bacnet();
380
- *
381
- * client.on('timeSyncUTC', (request) => {
382
- * console.log('address: ', device.address, ' - dateTime: ', device.dateTime);
383
- * });
384
- */
385
- this.emit('timeSyncUTC', { address: address, dateTime: result.dateTime });
386
- } else if (service === baEnum.UnconfirmedServiceChoice.UNCONFIRMED_EVENT_NOTIFICATION) {
387
- result = baServices.eventNotifyData.decode(buffer, offset, length);
388
- if (!result) return debug('Received invalid EventNotify message');
389
- this.emit('eventNotify', { address: address, eventData: result.eventData });
390
- } else if (service === baEnum.UnconfirmedServiceChoice.I_HAVE) {
391
- result = baServices.iHaveBroadcast.decode(buffer, offset, length);
392
- if (!result) return debug('Received invalid ihaveBroadcast message');
393
- this.emit('ihaveBroadcast', { address: address, eventData: result.eventData });
394
- } else if (service === baEnum.UnconfirmedServiceChoice.UNCONFIRMED_PRIVATE_TRANSFER) {
395
- result = baServices.privateTransfer.decode(buffer, offset, length);
396
- if (!result) return debug('Received invalid privateTransfer message');
397
- this.emit('privateTransfer', { address: address, eventData: result.eventData });
398
- } else {
399
- debug('Received unsupported unconfirmed service request');
400
- }
401
- }
402
-
403
- _handlePdu(address, type, buffer, offset, length, addressObject, destAddressObject, port) {
404
- let result;
405
- // Handle different PDU types
406
- switch (type & baEnum.PDU_TYPE_MASK) {
407
- case baEnum.PduTypes.UNCONFIRMED_REQUEST:
408
- result = baApdu.decodeUnconfirmedServiceRequest(buffer, offset);
409
- this._processUnconfirmedServiceRequest(address, result.type, result.service, buffer, offset + result.len, length - result.len, addressObject, port);
410
- break;
411
- case baEnum.PduTypes.SIMPLE_ACK:
412
- result = baApdu.decodeSimpleAck(buffer, offset);
413
- offset += result.len;
414
- length -= result.len;
415
- this._invokeCallback(result.invokeId, null, { result: result, buffer: buffer, offset: offset + result.len, length: length - result.len });
416
- break;
417
- case baEnum.PduTypes.COMPLEX_ACK:
418
- result = baApdu.decodeComplexAck(buffer, offset);
419
- if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) === 0) {
420
- this._invokeCallback(result.invokeId, null, { result: result, buffer: buffer, offset: offset + result.len, length: length - result.len });
421
- } else {
422
- this._processSegment(addressObject, result.type, result.service, result.invokeId, baEnum.MaxSegmentsAccepted.SEGMENTS_0, baEnum.MaxApduLengthAccepted.OCTETS_50, false, result.sequencenumber, result.proposedWindowNumber, buffer, offset + result.len, length - result.len, port);
423
- }
424
- break;
425
- case baEnum.PduTypes.SEGMENT_ACK:
426
- result = baApdu.decodeSegmentAck(buffer, offset);
427
- //m_last_segment_ack.Set(address, result.originalInvokeId, result.sequencenumber, result.actualWindowSize);
428
- //this._processSegmentAck(address, result.type, result.originalInvokeId, result.sequencenumber, result.actualWindowSize, buffer, offset + result.len, length - result.len);
429
- break;
430
- case baEnum.PduTypes.ERROR:
431
- result = baApdu.decodeError(buffer, offset);
432
- this._processError(result.invokeId, buffer, offset + result.len, length - result.len);
433
- break;
434
- case baEnum.PduTypes.REJECT:
435
- case baEnum.PduTypes.ABORT:
436
- result = baApdu.decodeAbort(buffer, offset);
437
- this._processAbort(result.invokeId, result.reason);
438
- break;
439
- case baEnum.PduTypes.CONFIRMED_REQUEST:
440
- result = baApdu.decodeConfirmedServiceRequest(buffer, offset);
441
- if ((type & baEnum.PduConReqBits.SEGMENTED_MESSAGE) === 0) {
442
- this._processConfirmedServiceRequest(address, result.type, result.service, result.maxSegments, result.maxApdu, result.invokeId, buffer, offset + result.len, length - result.len, addressObject, destAddressObject);
443
- } else {
444
- this._processSegment(address, result.type, result.service, result.invokeId, result.maxSegments, result.maxApdu, true, result.sequencenumber, result.proposedWindowNumber, buffer, offset + result.len, length - result.len, port);
445
- }
446
- break;
447
- default:
448
- debug('Received unknown PDU type -> Drop package');
449
- break;
450
- }
451
- }
452
- _handleNpdu(buffer, offset, msgLength, remoteAddress, port) {
453
- // Check data length
454
- if (msgLength <= 0) return debug('No NPDU data -> Drop package');
455
- // Parse baNpdu header
456
- const result = baNpdu.decode(buffer, offset);
457
- var addressObject, destAddress;
458
- // @todo a MSTP Dest & Source could occur. this case is not handled.
459
- if (typeof (result.source) != 'undefined' && result && result.source) {
460
- addressObject = result.source;
461
- addressObject.ip = remoteAddress;
462
- } else {
463
- addressObject = remoteAddress;
464
- }
465
-
466
- if (typeof (result.destination) != 'undefined') {
467
- destAddress = result.destination;
468
- destAddress.ip = remoteAddress;
469
- } else {
470
- destAddress = remoteAddress;
471
- }
472
-
473
- if (!result) return debug('Received invalid NPDU header -> Drop package');
474
- if (result.funct & baEnum.NpduControlBits.NETWORK_LAYER_MESSAGE) {
475
- return debug('Received network layer message -> Drop package');
476
- }
477
- offset += result.len;
478
- msgLength -= result.len;
479
- if (msgLength <= 0) return debug('No APDU data -> Drop package');
480
- const apduType = baApdu.getDecodedType(buffer, offset);
481
- this._handlePdu(remoteAddress, apduType, buffer, offset, msgLength, addressObject, destAddress, port);
482
- }
483
- _receiveData(buffer, remoteAddress, port) {
484
- // Check data length
485
- if (buffer.length < baEnum.BVLC_HEADER_LENGTH)
486
- return debug('Received invalid data -> Drop package');
487
- // Parse BVLC header
488
- const result = baBvlc.decode(buffer, 0);
489
- if (!result)
490
- return debug('Received invalid BVLC header -> Drop package');
491
- // Check BVLC function
492
- if (result.func === baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU || result.func === baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU || result.func === baEnum.BvlcResultPurpose.FORWARDED_NPDU) {
493
- this._handleNpdu(buffer, result.len, buffer.length - result.len, remoteAddress, port);
494
- }
495
- else {
496
- debug('Received unknown BVLC function -> Drop package');
497
- }
498
- }
499
- _receiveError(err) {
500
- /**
501
- * @event bacstack.error
502
- * @param {error} err - The error object thrown by the underlying transport layer.
503
- * @example
504
- * const bacnet = require('bacstack');
505
- * const client = new bacnet();
506
- *
507
- * client.on('error', (err) => {
508
- * console.log('Error occurred: ', err);
509
- * client.close();
510
- * });
511
- */
512
- this.emit('error', err);
513
- }
514
- /**
515
- * The whoIs command discovers all BACNET devices in a network.
516
- * @function bacstack.whoIs
517
- * @param {object=} options
518
- * @param {number=} options.lowLimit - Minimal device instance number to search for.
519
- * @param {number=} options.highLimit - Maximal device instance number to search for.
520
- * @param {string=} options.address - Unicast address if command should address a device directly.
521
- * @fires bacstack.iAm
522
- * @example
523
- * const bacnet = require('bacstack');
524
- * const client = new bacnet();
525
- *
526
- * client.whoIs();
527
-
528
- whoIs(options) {
529
- options = options || {};
530
- const settings = {
531
- lowLimit: options.lowLimit,
532
- highLimit: options.highLimit,
533
- address: options.address || this._transport.getBroadcastAddress()
534
- };
535
- const buffer = this._getBuffer();
536
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, this._settings.address, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
537
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.WHO_IS);
538
- baServices.whoIs.encode(buffer, settings.lowLimit, settings.highLimit);
539
- const npduType = (this._settings.address !== this._transport.getBroadcastAddress()) ? baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU : baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU;
540
- baBvlc.encode(buffer.buffer, npduType, buffer.offset);
541
- this._transport.send(buffer.buffer, buffer.offset, settings.address);
542
- }
543
- */
544
- whoIs(receiver, options) {
545
- if (!options) {
546
- if (
547
- receiver &&
548
- typeof receiver === 'object' &&
549
- receiver.address === undefined &&
550
- receiver.forwardedFrom === undefined &&
551
- (receiver.lowLimit !== undefined || receiver.highLimit !== undefined)
552
- ) {
553
- // receiver seems to be an options object
554
- options = receiver;
555
- receiver = undefined;
556
- }
557
- }
558
- options = options || {};
559
-
560
- const settings = {
561
- lowLimit: options.lowLimit,
562
- highLimit: options.highLimit,
563
- };
564
- const buffer = this._getBuffer(receiver && receiver.forwardedFrom);
565
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
566
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.WHO_IS);
567
- baServices.whoIs.encode(buffer, settings.lowLimit, settings.highLimit);
568
- this.sendBvlc(receiver, this._settings.portRangeMatrix, buffer);
569
- }
570
- /**
571
- * The timeSync command sets the time of a target device.
572
- * @function bacstack.timeSync
573
- * @param {string} address - IP address of the target device.
574
- * @param {date} dateTime - The date and time to set on the target device.
575
- * @example
576
- * const bacnet = require('bacstack');
577
- * const client = new bacnet();
578
- *
579
- * client.timeSync('192.168.1.43', new Date());
580
- */
581
- timeSync(addressObject, dateTime) {
582
- let address = addressObject.address ? addressObject.address : addressObject;
583
- let port = addressObject.port ? addressObject.port : this._settings.port;
584
-
585
- const buffer = this._getBuffer();
586
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, address);
587
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.TIME_SYNCHRONIZATION);
588
- baServices.timeSync.encode(buffer, dateTime);
589
- const npduType = (address !== this._transport.getBroadcastAddress()) ? baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU : baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU;
590
- //baBvlc.encode(buffer.buffer, npduType, buffer.offset);
591
- this.sendBvlc(address, port, buffer);
592
- }
593
- /**
594
- * The timeSyncUTC command sets the UTC time of a target device.
595
- * @function bacstack.timeSyncUTC
596
- * @param {string} address - IP address of the target device.
597
- * @param {date} dateTime - The date and time to set on the target device.
598
- * @example
599
- * const bacnet = require('bacstack');
600
- * const client = new bacnet();
601
- *
602
- * client.timeSyncUTC('192.168.1.43', new Date());
603
- */
604
- timeSyncUTC(addressObject, dateTime) {
605
- let address = addressObject.address ? addressObject.address : addressObject;
606
- let port = addressObject.port ? addressObject.port : this._settings.port;
607
- const buffer = this._getBuffer();
608
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, address);
609
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.UTC_TIME_SYNCHRONIZATION);
610
- baServices.timeSync.encode(buffer, dateTime);
611
- const npduType = (address !== this._transport.getBroadcastAddress()) ? baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU : baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU;
612
- //baBvlc.encode(buffer.buffer, npduType, buffer.offset);
613
- this.sendBvlc(address, port, buffer);
614
- }
615
- /**
616
- * The readProperty command reads a single property of an object from a device.
617
- * @function bacstack.readProperty
618
- * @param {string} address - IP address of the target device.
619
- * @param {object} objectId - The BACNET object ID to read.
620
- * @param {number} objectId.type - The BACNET object type to read.
621
- * @param {number} objectId.instance - The BACNET object instance to read.
622
- * @param {number} propertyId - The BACNET property id in the specified object to read.
623
- * @param {object=} options
624
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
625
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
626
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
627
- * @param {number=} options.arrayIndex - The array index of the property to be read.
628
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
629
- * @example
630
- * const bacnet = require('bacstack');
631
- * const client = new bacnet();
632
- *
633
- * client.readProperty('192.168.1.43', {type: 8, instance: 44301}, 28, (err, value) => {
634
- * console.log('value: ', value);
635
- * });
636
- */
637
- readProperty(addressObject, objectId, propertyId, options, next) {
638
- next = next || options;
639
-
640
- let address = addressObject.address ? addressObject.address : addressObject;
641
- let port = addressObject.port ? addressObject.port : this._settings.port;
642
-
643
- const settings = {
644
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
645
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
646
- invokeId: options.invokeId || this._getInvokeId(),
647
- arrayIndex: options.arrayIndex || baEnum.ASN1_ARRAY_ALL
648
- };
649
- const buffer = this._getBuffer();
650
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
651
- const type = baEnum.PduTypes.CONFIRMED_REQUEST | (settings.maxSegments !== baEnum.MaxSegmentsAccepted.SEGMENTS_0 ? baEnum.PduConReqBits.SEGMENTED_RESPONSE_ACCEPTED : 0);
652
- baApdu.encodeConfirmedServiceRequest(buffer, type, baEnum.ConfirmedServiceChoice.READ_PROPERTY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
653
- baServices.readProperty.encode(buffer, objectId.type, objectId.instance, propertyId, settings.arrayIndex);
654
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
655
- this.sendBvlc(address, port, buffer);
656
- this._addCallback(settings.invokeId, (err, data) => {
657
- try {
658
- if (err)
659
- return next(err);
660
- const result = baServices.readProperty.decodeAcknowledge(data.buffer, data.offset, data.length);
661
- if (!result)
662
- return next(new Error('INVALID_DECODING'));
663
- next(null, result);
664
- } catch (e) {
665
- return next(e);
666
- }
667
- });
668
- }
669
- /**
670
- * The writeProperty command writes a single property of an object to a device.
671
- * @function bacstack.writeProperty
672
- * @param {string} address - IP address of the target device.
673
- * @param {object} objectId - The BACNET object ID to write.
674
- * @param {number} objectId.type - The BACNET object type to write.
675
- * @param {number} objectId.instance - The BACNET object instance to write.
676
- * @param {number} propertyId - The BACNET property id in the specified object to write.
677
- * @param {object[]} values - A list of values to be written to the specified property.
678
- * @param {ApplicationTags} values.tag - The data-type of the value to be written.
679
- * @param {number} values.value - The actual value to be written.
680
- * @param {object=} options
681
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
682
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
683
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
684
- * @param {number=} options.arrayIndex - The array index of the property to be read.
685
- * @param {number=} options.priority - The priority of the value to be written.
686
- * @param {function} next - The callback containing an error, in case of a failure.
687
- * @example
688
- * const bacnet = require('bacstack');
689
- * const client = new bacnet();
690
- *
691
- * client.writeProperty('192.168.1.43', {type: 8, instance: 44301}, 28, [
692
- * {type: bacnet.enum.ApplicationTags.REAL, value: 100}
693
- * ], (err) => {
694
- * console.log('error: ', err);
695
- * });
696
- */
697
- writeProperty(addressObject, objectId, propertyId, values, options, next) {
698
- next = next || options;
699
-
700
- let address = addressObject.address ? addressObject.address : addressObject;
701
- let port = addressObject.port ? addressObject.port : this._settings.port;
702
-
703
- const settings = {
704
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
705
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
706
- invokeId: options.invokeId || this._getInvokeId(),
707
- arrayIndex: options.arrayIndex || baEnum.ASN1_ARRAY_ALL,
708
- priority: options.priority
709
- };
710
- const buffer = this._getBuffer();
711
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
712
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.WRITE_PROPERTY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
713
- baServices.writeProperty.encode(buffer, objectId.type, objectId.instance, propertyId, settings.arrayIndex, settings.priority, values);
714
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
715
- this.sendBvlc(address, port, buffer);
716
- this._addCallback(settings.invokeId, (err) => next(err));
717
- }
718
- /**
719
- * The readPropertyMultiple command reads multiple properties in multiple objects from a device.
720
- * @function bacstack.readPropertyMultiple
721
- * @param {string} address - IP address of the target device.
722
- * @param {object[]} propertiesArray - List of object and property specifications to be read.
723
- * @param {object} propertiesArray.objectId - Specifies which object to read.
724
- * @param {number} propertiesArray.objectId.type - The BACNET object type to read.
725
- * @param {number} propertiesArray.objectId.instance - The BACNET object instance to read.
726
- * @param {object[]} propertiesArray.properties - List of properties to be read.
727
- * @param {number} propertiesArray.properties.id - The BACNET property id in the specified object to read. Also supports 8 for all properties.
728
- * @param {object=} options
729
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
730
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
731
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
732
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
733
- * @example
734
- * const bacnet = require('bacstack');
735
- * const client = new bacnet();
736
- *
737
- * const propertiesArray = [
738
- * {objectId: {type: 8, instance: 4194303}, properties: [{id: 8}]}
739
- * ];
740
- * client.readPropertyMultiple('192.168.1.43', propertiesArray, (err, value) => {
741
- * console.log('value: ', value);
742
- * });
743
- */
744
- readPropertyMultiple(addressObject, propertiesArray, options, next) {
745
- next = next || options;
746
-
747
- let address = addressObject.address ? addressObject.address : addressObject;
748
- let port = addressObject.port ? addressObject.port : this._settings.port;
749
-
750
- const settings = {
751
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
752
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
753
- invokeId: options.invokeId || this._getInvokeId()
754
- };
755
- const buffer = this._getBuffer();
756
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
757
- const type = baEnum.PduTypes.CONFIRMED_REQUEST | (settings.maxSegments !== baEnum.MaxSegmentsAccepted.SEGMENTS_0 ? baEnum.PduConReqBits.SEGMENTED_RESPONSE_ACCEPTED : 0);
758
- baApdu.encodeConfirmedServiceRequest(buffer, type, baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
759
- baServices.readPropertyMultiple.encode(buffer, propertiesArray);
760
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
761
- this.sendBvlc(address, port, buffer);
762
- this._addCallback(settings.invokeId, (err, data) => {
763
- try {
764
- if (err)
765
- return next(err);
766
- const result = baServices.readPropertyMultiple.decodeAcknowledge(data.buffer, data.offset, data.length);
767
- if (!result)
768
- return next(new Error('INVALID_DECODING'));
769
- next(null, result);
770
- } catch (e) {
771
- return next(e);
772
- }
773
- });
774
- }
775
- /**
776
- * The writePropertyMultiple command writes multiple properties in multiple objects to a device.
777
- * @function bacstack.writePropertyMultiple
778
- * @param {string} address - IP address of the target device.
779
- * @param {object[]} values - List of object and property specifications to be written.
780
- * @param {object} values.objectId - Specifies which object to read.
781
- * @param {number} values.objectId.type - The BACNET object type to read.
782
- * @param {number} values.objectId.instance - The BACNET object instance to read.
783
- * @param {object[]} values.values - List of properties to be written.
784
- * @param {object} values.values.property - Property specifications to be written.
785
- * @param {number} values.values.property.id - The BACNET property id in the specified object to write.
786
- * @param {number} values.values.property.index - The array index of the property to be written.
787
- * @param {object[]} values.values.value - A list of values to be written to the specified property.
788
- * @param {ApplicationTags} values.values.value.tag - The data-type of the value to be written.
789
- * @param {object} values.values.value.value - The actual value to be written.
790
- * @param {number} values.values.priority - The priority to be used for writing to the property.
791
- * @param {object=} options
792
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
793
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
794
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
795
- * @param {function} next - The callback containing an error, in case of a failure.
796
- * @example
797
- * const bacnet = require('bacstack');
798
- * const client = new bacnet();
799
- *
800
- * const values = [
801
- * {objectId: {type: 8, instance: 44301}, values: [
802
- * {property: {id: 28, index: 12}, value: [{type: bacnet.enum.ApplicationTags.BOOLEAN, value: true}], priority: 8}
803
- * ]}
804
- * ];
805
- * client.writePropertyMultiple('192.168.1.43', values, (err) => {
806
- * console.log('error: ', err);
807
- * });
808
- */
809
- writePropertyMultiple(addressObject, values, options, next) {
810
- next = next || options;
811
-
812
- let address = addressObject.address ? addressObject.address : addressObject;
813
- let port = addressObject.port ? addressObject.port : this._settings.port;
814
-
815
- const settings = {
816
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
817
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
818
- invokeId: options.invokeId || this._getInvokeId()
819
- };
820
- const buffer = this._getBuffer();
821
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
822
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.WRITE_PROPERTY_MULTIPLE, settings.maxSegments, settings.maxApdu, settings.invokeId);
823
- baServices.writePropertyMultiple.encodeObject(buffer, values);
824
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
825
- this.sendBvlc(address, port, buffer);
826
- this._addCallback(settings.invokeId, (err) => next(err));
827
- }
828
- /**
829
- * The deviceCommunicationControl command enables or disables network communication of the target device.
830
- * @function bacstack.deviceCommunicationControl
831
- * @param {string} address - IP address of the target device.
832
- * @param {number} timeDuration - The time to hold the network communication state in seconds. 0 for infinite.
833
- * @param {EnableDisable} enableDisable - The network communication state to set.
834
- * @param {object=} options
835
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
836
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
837
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
838
- * @param {string=} options.password - The optional password used to set the network communication state.
839
- * @param {function} next - The callback containing an error, in case of a failure.
840
- * @example
841
- * const bacnet = require('bacstack');
842
- * const client = new bacnet();
843
- *
844
- * client.deviceCommunicationControl('192.168.1.43', 0, bacnet.enum.EnableDisable.DISABLE, (err) => {
845
- * console.log('error: ', err);
846
- * });
847
- */
848
- deviceCommunicationControl(addressObject, timeDuration, enableDisable, options, next) {
849
- next = next || options;
850
- let address = addressObject.address ? addressObject.address : addressObject;
851
- let port = addressObject.port ? addressObject.port : this._settings.port;
852
- const settings = {
853
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
854
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
855
- invokeId: options.invokeId || this._getInvokeId(),
856
- password: options.password
857
- };
858
- const buffer = this._getBuffer();
859
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
860
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.DEVICE_COMMUNICATION_CONTROL, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
861
- baServices.deviceCommunicationControl.encode(buffer, timeDuration, enableDisable, settings.password);
862
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
863
- this.sendBvlc(address, port, buffer);
864
- this._addCallback(settings.invokeId, (err) => next(err));
865
- }
866
- /**
867
- * The reinitializeDevice command initiates a restart of the target device.
868
- * @function bacstack.reinitializeDevice
869
- * @param {string} address - IP address of the target device.
870
- * @param {ReinitializedState} state - The type of restart to be initiated.
871
- * @param {object=} options
872
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
873
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
874
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
875
- * @param {string=} options.password - The optional password used to restart the device.
876
- * @param {function} next - The callback containing an error, in case of a failure.
877
- * @example
878
- * const bacnet = require('bacstack');
879
- * const client = new bacnet();
880
- *
881
- * client.reinitializeDevice('192.168.1.43', bacnet.enum.ReinitializedState.COLDSTART, (err) => {
882
- * console.log('error: ', err);
883
- * });
884
- */
885
- reinitializeDevice(addressObject, state, options, next) {
886
- next = next || options;
887
- let address = addressObject.address ? addressObject.address : addressObject;
888
- let port = addressObject.port ? addressObject.port : this._settings.port;
889
- const settings = {
890
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
891
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
892
- invokeId: options.invokeId || this._getInvokeId(),
893
- password: options.password
894
- };
895
- const buffer = this._getBuffer();
896
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
897
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.REINITIALIZE_DEVICE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
898
- baServices.reinitializeDevice.encode(buffer, state, settings.password);
899
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
900
- this.sendBvlc(address, port, buffer);
901
- this._addCallback(settings.invokeId, (err) => next(err));
902
- }
903
- /**
904
- * The writeFile command writes a file buffer to a specific position of a file object.
905
- * @function bacstack.writeFile
906
- * @param {string} address - IP address of the target device.
907
- * @param {object} objectId - The BACNET object ID representing the file object.
908
- * @param {number} objectId.type - The BACNET object type representing the file object.
909
- * @param {number} objectId.instance - The BACNET object instance representing the file object.
910
- * @param {number} position - The position in the file to write at.
911
- * @param {Array.<number[]>} fileBuffer - The content to be written to the file.
912
- * @param {object=} options
913
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
914
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
915
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
916
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
917
- * @example
918
- * const bacnet = require('bacstack');
919
- * const client = new bacnet();
920
- *
921
- * client.writeFile('192.168.1.43', {type: 8, instance: 44301}, 0, [[5, 6, 7, 8], [5, 6, 7, 8]], (err, value) => {
922
- * console.log('value: ', value);
923
- * });
924
- */
925
- writeFile(addressObject, objectId, position, fileBuffer, options, next) {
926
- next = next || options;
927
- let address = addressObject.address ? addressObject.address : addressObject;
928
- let port = addressObject.port ? addressObject.port : this._settings.port;
929
- const settings = {
930
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
931
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
932
- invokeId: options.invokeId || this._getInvokeId()
933
- };
934
- const buffer = this._getBuffer();
935
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
936
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.ATOMIC_WRITE_FILE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
937
- baServices.atomicWriteFile.encode(buffer, false, objectId, position, fileBuffer);
938
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
939
- this.sendBvlc(address, port, buffer);
940
- this._addCallback(settings.invokeId, (err, data) => {
941
- if (err)
942
- return next(err);
943
- const result = baServices.atomicWriteFile.decodeAcknowledge(data.buffer, data.offset);
944
- if (!result)
945
- return next(new Error('INVALID_DECODING'));
946
- next(null, result);
947
- });
948
- }
949
- /**
950
- * The readFile command reads a number of bytes at a specific position of a file object.
951
- * @function bacstack.readFile
952
- * @param {string} address - IP address of the target device.
953
- * @param {object} objectId - The BACNET object ID representing the file object.
954
- * @param {number} objectId.type - The BACNET object type representing the file object.
955
- * @param {number} objectId.instance - The BACNET object instance representing the file object.
956
- * @param {number} position - The position in the file to read at.
957
- * @param {number} count - The number of octets to read.
958
- * @param {object=} options
959
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
960
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
961
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
962
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
963
- * @example
964
- * const bacnet = require('bacstack');
965
- * const client = new bacnet();
966
- *
967
- * client.readFile('192.168.1.43', {type: 8, instance: 44301}, 0, 100, (err, value) => {
968
- * console.log('value: ', value);
969
- * });
970
- */
971
- readFile(addressObject, objectId, position, count, options, next) {
972
- next = next || options;
973
- let address = addressObject.address ? addressObject.address : addressObject;
974
- let port = addressObject.port ? addressObject.port : this._settings.port;
975
- const settings = {
976
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
977
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
978
- invokeId: options.invokeId || this._getInvokeId()
979
- };
980
- const buffer = this._getBuffer();
981
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
982
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.ATOMIC_READ_FILE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
983
- baServices.atomicReadFile.encode(buffer, true, objectId, position, count);
984
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
985
- this.sendBvlc(address, port, buffer);
986
- this._addCallback(settings.invokeId, (err, data) => {
987
- if (err)
988
- return next(err);
989
- const result = baServices.atomicReadFile.decodeAcknowledge(data.buffer, data.offset);
990
- if (!result)
991
- return next(new Error('INVALID_DECODING'));
992
- next(null, result);
993
- });
994
- }
995
- /**
996
- * The readRange command reads a number if list items of an array or list object.
997
- * @function bacstack.readRange
998
- * @param {string} address - IP address of the target device.
999
- * @param {object} objectId - The BACNET object ID to read.
1000
- * @param {number} objectId.type - The BACNET object type to read.
1001
- * @param {number} objectId.instance - The BACNET object instance to read.
1002
- * @param {number} idxBegin - The index of the first/last item to read.
1003
- * @param {number} quantity - The number of records to read.
1004
- * @param {object=} options
1005
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1006
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1007
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1008
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
1009
- * @example
1010
- * const bacnet = require('bacstack');
1011
- * const client = new bacnet();
1012
- *
1013
- * client.readRange('192.168.1.43', {type: 8, instance: 44301}, 0, 200, (err, value) => {
1014
- * console.log('value: ', value);
1015
- * });
1016
- */
1017
- readRange(addressObject, objectId, idxBegin, quantity, options, next) {
1018
- next = next || options;
1019
- let address = addressObject.address ? addressObject.address : addressObject;
1020
- let port = addressObject.port ? addressObject.port : this._settings.port;
1021
- const settings = {
1022
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1023
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1024
- invokeId: options.invokeId || this._getInvokeId()
1025
- };
1026
- const buffer = this._getBuffer();
1027
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1028
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.READ_RANGE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1029
- baServices.readRange.encode(buffer, objectId, baEnum.PropertyIdentifier.LOG_BUFFER, baEnum.ASN1_ARRAY_ALL, baEnum.ReadRangeType.BY_POSITION, idxBegin, new Date(), quantity);
1030
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1031
- this.sendBvlc(address, port, buffer);
1032
- this._addCallback(settings.invokeId, (err, data) => {
1033
- if (err)
1034
- return next(err);
1035
- const result = baServices.readRange.decodeAcknowledge(data.buffer, data.offset, data.length);
1036
- if (!result)
1037
- return next(new Error('INVALID_DECODING'));
1038
- next(null, result);
1039
- });
1040
- }
1041
- /**
1042
- * The subscribeCOV command subscribes to an object for "Change of Value" notifications.
1043
- * @function bacstack.subscribeCOV
1044
- * @param {string} address - IP address of the target device.
1045
- * @param {object} objectId - The BACNET object ID to subscribe for.
1046
- * @param {number} objectId.type - The BACNET object type to subscribe for.
1047
- * @param {number} objectId.instance - The BACNET object instance to subscribe for.
1048
- * @param {number} subscribeId - A unique identifier to map the subscription.
1049
- * @param {boolean} cancel - Cancel an existing subscription instead of creating a new one.
1050
- * @param {boolean} issueConfirmedNotifications - Identifies if unconfirmed/confirmed notifications shall be returned.
1051
- * @param {number} lifetime - Number of seconds for the subscription to stay active, 0 for infinite.
1052
- * @param {object=} options
1053
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1054
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1055
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1056
- * @param {function} next - The callback containing an error, in case of a failure.
1057
- * @example
1058
- * const bacnet = require('bacstack');
1059
- * const client = new bacnet();
1060
- *
1061
- * client.subscribeCOV('192.168.1.43', {type: 8, instance: 44301}, 7, false, false, 0, (err) => {
1062
- * console.log('error: ', err);
1063
- * });
1064
- */
1065
- subscribeCOV(addressObject, objectId, subscribeId, cancel, issueConfirmedNotifications, lifetime, options, next) {
1066
- next = next || options;
1067
- let address = addressObject.address ? addressObject.address : addressObject;
1068
- let port = addressObject.port ? addressObject.port : this._settings.port;
1069
- const settings = {
1070
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1071
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1072
- invokeId: options.invokeId || this._getInvokeId()
1073
- };
1074
- const buffer = this._getBuffer();
1075
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1076
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.SUBSCRIBE_COV, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1077
- baServices.subscribeCov.encode(buffer, subscribeId, objectId, cancel, issueConfirmedNotifications, lifetime);
1078
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1079
- this.sendBvlc(address, port, buffer);
1080
- this._addCallback(settings.invokeId, (err) => next(err));
1081
- }
1082
- /**
1083
- * The subscribeProperty command subscribes to a specific property of an object for "Change of Value" notifications.
1084
- * @function bacstack.subscribeProperty
1085
- * @param {string} address - IP address of the target device.
1086
- * @param {object} objectId - The BACNET object ID to subscribe for.
1087
- * @param {number} objectId.type - The BACNET object type to subscribe for.
1088
- * @param {number} objectId.instance - The BACNET object instance to subscribe for.
1089
- * @param {object} monitoredProperty
1090
- * @param {object} monitoredProperty.id - The property ID to subscribe for.
1091
- * @param {object} monitoredProperty.index - The property index to subscribe for.
1092
- * @param {number} subscribeId - A unique identifier to map the subscription.
1093
- * @param {boolean} cancel - Cancel an existing subscription instead of creating a new one.
1094
- * @param {boolean} issueConfirmedNotifications - Identifies if unconfirmed/confirmed notifications shall be returned.
1095
- * @param {object=} options
1096
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1097
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1098
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1099
- * @param {function} next - The callback containing an error, in case of a failure.
1100
- * @example
1101
- * const bacnet = require('bacstack');
1102
- * const client = new bacnet();
1103
- *
1104
- * client.subscribeProperty('192.168.1.43', {type: 8, instance: 44301}, {id: 80, index: 0}, 8, false, false, (err) => {
1105
- * console.log('error: ', err);
1106
- * });
1107
- */
1108
- subscribeProperty(addressObject, objectId, monitoredProperty, subscribeId, cancel, issueConfirmedNotifications, options, next) {
1109
- next = next || options;
1110
- let address = addressObject.address ? addressObject.address : addressObject;
1111
- let port = addressObject.port ? addressObject.port : this._settings.port;
1112
- const settings = {
1113
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1114
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1115
- invokeId: options.invokeId || this._getInvokeId()
1116
- };
1117
- const buffer = this._getBuffer();
1118
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1119
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.SUBSCRIBE_COV_PROPERTY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1120
- baServices.subscribeProperty.encode(buffer, subscribeId, objectId, cancel, issueConfirmedNotifications, 0, monitoredProperty, false, 0x0f);
1121
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1122
- this.sendBvlc(address, port, buffer);
1123
- this._addCallback(settings.invokeId, (err) => next(err));
1124
- }
1125
- createObject(addressObject, objectId, values, options, next) {
1126
- next = next || options;
1127
- let address = addressObject.address ? addressObject.address : addressObject;
1128
- let port = addressObject.port ? addressObject.port : this._settings.port;
1129
- const settings = {
1130
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1131
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1132
- invokeId: options.invokeId || this._getInvokeId()
1133
- };
1134
- const buffer = this._getBuffer();
1135
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1136
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.CREATE_OBJECT, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1137
- baServices.createObject.encode(buffer, objectId, values);
1138
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1139
- this.sendBvlc(address, port, buffer);
1140
- this._addCallback(settings.invokeId, (err) => next(err));
1141
- }
1142
- /**
1143
- * The deleteObject command removes an object instance from a target device.
1144
- * @function bacstack.deleteObject
1145
- * @param {string} address - IP address of the target device.
1146
- * @param {object} objectId - The BACNET object ID to delete.
1147
- * @param {number} objectId.type - The BACNET object type to delete.
1148
- * @param {number} objectId.instance - The BACNET object instance to delete.
1149
- * @param {object=} options
1150
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1151
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1152
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1153
- * @param {function} next - The callback containing an error, in case of a failure.
1154
- * @example
1155
- * const bacnet = require('bacstack');
1156
- * const client = new bacnet();
1157
- *
1158
- * client.deleteObject('192.168.1.43', {type: 8, instance: 44301}, (err) => {
1159
- * console.log('error: ', err);
1160
- * });
1161
- */
1162
- deleteObject(addressObject, objectId, options, next) {
1163
- next = next || options;
1164
- let address = addressObject.address ? addressObject.address : addressObject;
1165
- let port = addressObject.port ? addressObject.port : this._settings.port;
1166
- const settings = {
1167
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1168
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1169
- invokeId: options.invokeId || this._getInvokeId()
1170
- };
1171
- const buffer = this._getBuffer();
1172
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1173
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.DELETE_OBJECT, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1174
- baServices.deleteObject.encode(buffer, objectId);
1175
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1176
- this.sendBvlc(address, port, buffer);
1177
- this._addCallback(settings.invokeId, (err) => next(err));
1178
- }
1179
- removeListElement(addressObject, objectId, reference, values, options, next) {
1180
- next = next || options;
1181
- let address = addressObject.address ? addressObject.address : addressObject;
1182
- let port = addressObject.port ? addressObject.port : this._settings.port;
1183
- const settings = {
1184
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1185
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1186
- invokeId: options.invokeId || this._getInvokeId()
1187
- };
1188
- const buffer = this._getBuffer();
1189
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1190
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.REMOVE_LIST_ELEMENT, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1191
- baServices.addListElement.encode(buffer, objectId, reference.id, reference.index, values);
1192
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1193
- this.sendBvlc(address, port, buffer);
1194
- this._addCallback(settings.invokeId, (err) => next(err));
1195
- }
1196
- addListElement(addressObject, objectId, reference, values, options, next) {
1197
- next = next || options;
1198
- let address = addressObject.address ? addressObject.address : addressObject;
1199
- let port = addressObject.port ? addressObject.port : this._settings.port;
1200
- const settings = {
1201
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1202
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1203
- invokeId: options.invokeId || this._getInvokeId()
1204
- };
1205
- const buffer = this._getBuffer();
1206
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1207
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.ADD_LIST_ELEMENT, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1208
- baServices.addListElement.encode(buffer, objectId, reference.id, reference.index, values);
1209
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1210
- this.sendBvlc(address, port, buffer);
1211
- this._addCallback(settings.invokeId, (err) => next(err));
1212
- }
1213
- /**
1214
- * DEPRECATED The getAlarmSummary command returns a list of all active alarms on the target device.
1215
- * @function bacstack.getAlarmSummary
1216
- * @param {string} address - IP address of the target device.
1217
- * @param {object=} options
1218
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1219
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1220
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1221
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
1222
- * @example
1223
- * const bacnet = require('bacstack');
1224
- * const client = new bacnet();
1225
- *
1226
- * client.getAlarmSummary('192.168.1.43', (err, value) => {
1227
- * console.log('value: ', value);
1228
- * });
1229
- */
1230
- getAlarmSummary(addressObject, options, next) {
1231
- next = next || options;
1232
- let address = addressObject.address ? addressObject.address : addressObject;
1233
- let port = addressObject.port ? addressObject.port : this._settings.port;
1234
- const settings = {
1235
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1236
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1237
- invokeId: options.invokeId || this._getInvokeId()
1238
- };
1239
- const buffer = this._getBuffer();
1240
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1241
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.GET_ALARM_SUMMARY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1242
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1243
- this.sendBvlc(address, port, buffer);
1244
- this._addCallback(settings.invokeId, (err, data) => {
1245
- if (err)
1246
- return next(err);
1247
- const result = baServices.alarmSummary.decode(data.buffer, data.offset, data.length);
1248
- if (!result)
1249
- return next(new Error('INVALID_DECODING'));
1250
- next(null, result);
1251
- });
1252
- }
1253
- /**
1254
- * The getEventInformation command returns a list of all active event states on the target device.
1255
- * @function bacstack.getEventInformation
1256
- * @param {string} address - IP address of the target device.
1257
- * @param {object=} objectId - The optional BACNET object ID to continue preceding calls.
1258
- * @param {number=} objectId.type - The optional BACNET object type to continue preceding calls.
1259
- * @param {number=} objectId.instance - The optional BACNET object instance to continue preceding calls.
1260
- * @param {object=} options
1261
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1262
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1263
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1264
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
1265
- * @example
1266
- * const bacnet = require('bacstack');
1267
- * const client = new bacnet();
1268
- *
1269
- * client.getEventInformation('192.168.1.43', {}, (err, value) => {
1270
- * console.log('value: ', value);
1271
- * });
1272
- */
1273
- getEventInformation(addressObject, objectId, options, next) {
1274
- next = next || options;
1275
- let address = addressObject.address ? addressObject.address : addressObject;
1276
- let port = addressObject.port ? addressObject.port : this._settings.port;
1277
- const settings = {
1278
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1279
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1280
- invokeId: options.invokeId || this._getInvokeId()
1281
- };
1282
- const buffer = this._getBuffer();
1283
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1284
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.GET_EVENT_INFORMATION, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1285
- baAsn1.encodeContextObjectId(buffer, 0, objectId.type, objectId.instance);
1286
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1287
- this.sendBvlc(address, port, buffer);
1288
- this._addCallback(settings.invokeId, (err, data) => {
1289
- if (err)
1290
- return next(err);
1291
- const result = baServices.eventInformation.decode(data.buffer, data.offset, data.length);
1292
- if (!result)
1293
- return next(new Error('INVALID_DECODING'));
1294
- next(null, result);
1295
- });
1296
- }
1297
- acknowledgeAlarm(addressObject, objectId, eventState, ackText, evTimeStamp, ackTimeStamp, options, next) {
1298
- next = next || options;
1299
- let address = addressObject.address ? addressObject.address : addressObject;
1300
- let port = addressObject.port ? addressObject.port : this._settings.port;
1301
- const settings = {
1302
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1303
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1304
- invokeId: options.invokeId || this._getInvokeId()
1305
- };
1306
- const buffer = this._getBuffer();
1307
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1308
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.ACKNOWLEDGE_ALARM, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1309
- baServices.alarmAcknowledge.encode(buffer, 57, objectId, eventState, ackText, evTimeStamp, ackTimeStamp);
1310
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1311
- this.sendBvlc(address, port, buffer);
1312
- this._addCallback(settings.invokeId, (err) => next(err));
1313
- }
1314
- /**
1315
- * The confirmedPrivateTransfer command invokes a confirmed proprietary/non-standard service.
1316
- * @function bacstack.confirmedPrivateTransfer
1317
- * @param {string} address - IP address of the target device.
1318
- * @param {number} vendorId - The unique vendor identification code.
1319
- * @param {number} serviceNumber - The unique service identifier.
1320
- * @param {number[]} [data] - Optional additional payload data.
1321
- * @param {object=} options
1322
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1323
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1324
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1325
- * @param {function} next - The callback containing an error, in case of a failure.
1326
- * @example
1327
- * const bacnet = require('bacstack');
1328
- * const client = new bacnet();
1329
- *
1330
- * client.confirmedPrivateTransfer('192.168.1.43', 0, 7, [0x00, 0xaa, 0xfa, 0xb1, 0x00], (err) => {
1331
- * console.log('error: ', err);
1332
- * });
1333
- */
1334
- confirmedPrivateTransfer(addressObject, vendorId, serviceNumber, data, options, next) {
1335
- next = next || options;
1336
- let address = addressObject.address ? addressObject.address : addressObject;
1337
- let port = addressObject.port ? addressObject.port : this._settings.port;
1338
- const settings = {
1339
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1340
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1341
- invokeId: options.invokeId || this._getInvokeId()
1342
- };
1343
- const buffer = this._getBuffer();
1344
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1345
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.CONFIRMED_PRIVATE_TRANSFER, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1346
- baServices.privateTransfer.encode(buffer, vendorId, serviceNumber, data);
1347
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1348
- this.sendBvlc(address, port, buffer);
1349
- this._addCallback(settings.invokeId, (err) => next(err));
1350
- }
1351
- /**
1352
- * The unconfirmedPrivateTransfer command invokes an unconfirmed proprietary/non-standard service.
1353
- * @function bacstack.unconfirmedPrivateTransfer
1354
- * @param {string} address - IP address of the target device.
1355
- * @param {number} vendorId - The unique vendor identification code.
1356
- * @param {number} serviceNumber - The unique service identifier.
1357
- * @param {number[]} [data] - Optional additional payload data.
1358
- * @example
1359
- * const bacnet = require('bacstack');
1360
- * const client = new bacnet();
1361
- *
1362
- * client.unconfirmedPrivateTransfer('192.168.1.43', 0, 7, [0x00, 0xaa, 0xfa, 0xb1, 0x00]);
1363
- */
1364
- unconfirmedPrivateTransfer(addressObject, vendorId, serviceNumber, data) {
1365
- const buffer = this._getBuffer();
1366
- let address = addressObject.address ? addressObject.address : addressObject;
1367
- let port = addressObject.port ? addressObject.port : this._settings.port;
1368
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, address);
1369
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.UNCONFIRMED_PRIVATE_TRANSFER);
1370
- baServices.privateTransfer.encode(buffer, vendorId, serviceNumber, data);
1371
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1372
- this.sendBvlc(address, port, buffer);
1373
- }
1374
- /**
1375
- * DEPRECATED The getEnrollmentSummary command returns a list of event-initiating objects on the target device.
1376
- * @function bacstack.getEnrollmentSummary
1377
- * @param {string} address - IP address of the target device.
1378
- * @param {number} acknowledgmentFilter - Filter for ALL/ACKED/NOT-ACKED, 0/1/2.
1379
- * @param {object=} options
1380
- * @param {object=} options.enrollmentFilter - Filter for enrollment.
1381
- * @param {EventState=} options.eventStateFilter - Filter for event state.
1382
- * @param {EventType=} options.eventTypeFilter - Filter for event type.
1383
- * @param {object=} options.priorityFilter
1384
- * @param {number} options.priorityFilter.min - Filter for minimal priority
1385
- * @param {number} options.priorityFilter.max - Filter for maximal priority
1386
- * @param {number=} options.notificationClassFilter - Filter for notification class.
1387
- * @param {MaxSegmentsAccepted=} options.maxSegments - The maximimal allowed number of segments.
1388
- * @param {MaxApduLengthAccepted=} options.maxApdu - The maximal allowed APDU size.
1389
- * @param {number=} options.invokeId - The invoke ID of the confirmed service telegram.
1390
- * @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
1391
- * @example
1392
- * const bacnet = require('bacstack');
1393
- * const client = new bacnet();
1394
- *
1395
- * client.getEnrollmentSummary('192.168.1.43', 0, (err, value) => {
1396
- * console.log('value: ', value);
1397
- * });
1398
- */
1399
- getEnrollmentSummary(addressObject, acknowledgmentFilter, options, next) {
1400
- next = next || options;
1401
- let address = addressObject.address ? addressObject.address : addressObject;
1402
- let port = addressObject.port ? addressObject.port : this._settings.port;
1403
- const settings = {
1404
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1405
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1406
- invokeId: options.invokeId || this._getInvokeId()
1407
- };
1408
- const buffer = this._getBuffer();
1409
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1410
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.GET_ENROLLMENT_SUMMARY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1411
- baServices.getEnrollmentSummary.encode(buffer, acknowledgmentFilter, options.enrollmentFilter, options.eventStateFilter, options.eventTypeFilter, options.priorityFilter, options.notificationClassFilter);
1412
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1413
- this.sendBvlc(address, port, buffer);
1414
- this._addCallback(settings.invokeId, (err, data) => {
1415
- if (err)
1416
- return next(err);
1417
- const result = baServices.getEnrollmentSummary.decodeAcknowledge(data.buffer, data.offset, data.length);
1418
- if (!result)
1419
- return next(new Error('INVALID_DECODING'));
1420
- next(null, result);
1421
- });
1422
- }
1423
- unconfirmedEventNotification(addressObject, eventNotification) {
1424
- let address = addressObject.address ? addressObject.address : addressObject;
1425
- let port = addressObject.port ? addressObject.port : this._settings.port;
1426
- const buffer = this._getBuffer();
1427
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, address);
1428
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.UNCONFIRMED_EVENT_NOTIFICATION);
1429
- baServices.eventNotifyData.encode(buffer, eventNotification);
1430
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1431
- this.sendBvlc(address, port, buffer);
1432
- }
1433
- confirmedEventNotification(addressObject, eventNotification, options, next) {
1434
- next = next || options;
1435
- let address = addressObject.address ? addressObject.address : addressObject;
1436
- let port = addressObject.port ? addressObject.port : this._settings.port;
1437
- const settings = {
1438
- maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
1439
- maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
1440
- invokeId: options.invokeId || this._getInvokeId()
1441
- };
1442
- const buffer = this._getBuffer();
1443
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
1444
- baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.CONFIRMED_EVENT_NOTIFICATION, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
1445
- baServices.eventNotifyData.encode(buffer, eventNotification);
1446
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1447
- this.sendBvlc(address, port, buffer);
1448
- this._addCallback(settings.invokeId, (err) => next(err));
1449
- }
1450
- // Public Device Functions
1451
- readPropertyResponse(receiver, invokeId, objectId, property, value) {
1452
- const buffer = this._getBuffer();
1453
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver);
1454
- baApdu.encodeComplexAck(buffer, baEnum.PduTypes.COMPLEX_ACK, baEnum.ConfirmedServiceChoice.READ_PROPERTY, invokeId);
1455
- baServices.readProperty.encodeAcknowledge(buffer, objectId, property.id, property.index, value);
1456
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1457
- this.sendBvlc(receiver, this._settings.port, buffer);
1458
- }
1459
- readPropertyMultipleResponse(receiver, invokeId, values) {
1460
- const buffer = this._getBuffer();
1461
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver);
1462
- baApdu.encodeComplexAck(buffer, baEnum.PduTypes.COMPLEX_ACK, baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE, invokeId);
1463
- baServices.readPropertyMultiple.encodeAcknowledge(buffer, values);
1464
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1465
- this.sendBvlc(receiver, this._settings.port, buffer);
1466
- }
1467
- iAmResponse(deviceId, segmentation, vendorId) {
1468
- const buffer = this._getBuffer();
1469
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, this._transport.getBroadcastAddress());
1470
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.I_AM);
1471
- baServices.iAmBroadcast.encode(buffer, deviceId, this._transport.getMaxPayload(), segmentation, vendorId);
1472
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU, buffer.offset);
1473
- this._transport.send(buffer.buffer, buffer.offset, this._transport.getBroadcastAddress(), this._settings.port);
1474
- }
1475
- iHaveResponse(deviceId, objectId, objectName) {
1476
- const buffer = this._getBuffer();
1477
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, this._transport.getBroadcastAddress());
1478
- baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.I_HAVE);
1479
- baServices.iHaveBroadcast.encode(buffer, deviceId, objectId, objectName);
1480
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU, buffer.offset);
1481
- this._transport.send(buffer.buffer, buffer.offset, this._transport.getBroadcastAddress(), this._settings.port);
1482
- }
1483
- simpleAckResponse(receiver, service, invokeId) {
1484
- const buffer = this._getBuffer();
1485
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver);
1486
- baApdu.encodeSimpleAck(buffer, baEnum.PduTypes.SIMPLE_ACK, service, invokeId);
1487
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1488
- this.sendBvlc(receiver, this._settings.port, buffer);
1489
- }
1490
- errorResponse(receiver, service, invokeId, errorClass, errorCode) {
1491
- const buffer = this._getBuffer();
1492
- baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, receiver);
1493
- baApdu.encodeError(buffer, baEnum.PduTypes.ERROR, service, invokeId);
1494
- baServices.error.encode(buffer, errorClass, errorCode);
1495
- //baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1496
- this.sendBvlc(receiver, this._settings.port, buffer);
1497
- }
1498
- /**
1499
- *
1500
- * @param receiver
1501
- * @param buffer
1502
- */
1503
- sendBvlc(receiver, port, buffer) {
1504
- let that = this;
1505
- if (typeof receiver === 'string') {
1506
- receiver = {
1507
- address: receiver
1508
- };
1509
- }
1510
- if (receiver && receiver.forwardedFrom) {
1511
- // Remote node address given, forward to BBMD
1512
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.FORWARDED_NPDU, buffer.offset, receiver.forwardedFrom);
1513
- } else if (receiver && receiver.address) {
1514
- // Specific address, unicast
1515
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
1516
- } else {
1517
- // No address, broadcast
1518
- baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_BROADCAST_NPDU, buffer.offset);
1519
- }
1520
-
1521
- //check if port is array, send on all specified ports if true
1522
- if (Array.isArray(port) && port.length > 0) {
1523
- port.forEach(function (p) {
1524
- that._transport.send(
1525
- buffer.buffer,
1526
- buffer.offset,
1527
- (receiver && receiver.address) || null,
1528
- p
1529
- );
1530
- });
1531
- } else {
1532
- this._transport.send(
1533
- buffer.buffer,
1534
- buffer.offset,
1535
- (receiver && receiver.address) || null,
1536
- port
1537
- );
1538
- }
1539
- }
1540
- /**
1541
- * Unloads the current BACstack instance and closes the underlying UDP socket.
1542
- * @function bacstack.close
1543
- * @example
1544
- * const bacnet = require('bacstack');
1545
- * const client = new bacnet();
1546
- *
1547
- * client.close();
1548
- */
1549
- close() {
1550
- this._transport.close();
1551
- }
1552
- }
1553
- exports.Client = Client;