Skip to content

Commit

Permalink
feat: add cov notification methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Deimbacher committed Dec 3, 2019
1 parent 6bbae54 commit a12bb30
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
111 changes: 111 additions & 0 deletions lib/client.js
Expand Up @@ -911,6 +911,117 @@ class Client extends EventEmitter {
});
}

/**
* The unconfirmedCOVNotification command sends an unconfirmed COV notification to a device
* @function bacstack.unconfirmedCOVNotification
* @param {string} address - IP address of the target device.
* @param {number} subscriberProcessId - The process id which was used by a target device in the subscription.
* @param {number} initiatingDeviceId - The id of this device.
* @param {object} monitoredObjectId - Specifies about which object the notification is.
* @param {number} monitoredObjectId.type - The BACNET object type of the notification.
* @param {number} monitoredObjectId.instance - The BACNET object instance of the notification.
* @param {number} timeRemaining - How long the subscription is still active in seconds.
* @param {object[]} values - List of properties with updated values.
* @param {object} values.property - Property specifications.
* @param {number} values.property.id - The updated BACNET property id.
* @param {number} values.property.index - The array index of the updated property.
* @param {object[]} values.value - A list of updated values.
* @param {ApplicationTags} values.value.type - The data-type of the updated value.
* @param {object} values.value.value - The actual updated value.
* @param {number} values.priority - The priority of the updated property.
* @example
* const bacnet = require('bacstack');
* const client = new bacnet();
*
* client.unconfirmedCOVNotification(
* '127.0.0.1',
* 3,
* 433,
* {type: 2, instance: 122},
* 120,
* [
* {
* property: {id: 85},
* value: [{type: baEnum.ApplicationTags.REAL, value: 12.3}]
* },
* {
* property: {id: 111},
* value: [{type: baEnum.ApplicationTags.BIT_STRING, value: 0xFFFF}]
* }
* ]);
*/
unconfirmedCOVNotification(address, subscriberProcessId, initiatingDeviceId, monitoredObjectId, timeRemaining, values) {
const buffer = this._getBuffer();
baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE, address);
baApdu.encodeUnconfirmedServiceRequest(buffer, baEnum.PduTypes.UNCONFIRMED_REQUEST, baEnum.UnconfirmedServiceChoice.UNCONFIRMED_COV_NOTIFICATION);
baServices.covNotify.encode(buffer, subscriberProcessId, initiatingDeviceId, monitoredObjectId, timeRemaining, values);
baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
this._transport.send(buffer.buffer, buffer.offset, address);
}

/**
* The unconfirmedCOVNotification command sends an unconfirmed COV notification to a device
* @function bacstack.unconfirmedCOVNotification
* @param {string} address - IP address of the target device.
* @param {number} subscriberProcessId - The process id which was used by a target device in the subscription.
* @param {number} initiatingDeviceId - The id of this device.
* @param {object} monitoredObjectId - Specifies about which object the notification is.
* @param {number} monitoredObjectId.type - The BACNET object type of the notification.
* @param {number} monitoredObjectId.instance - The BACNET object instance of the notification.
* @param {number} timeRemaining - How long the subscription is still active in seconds.
* @param {object[]} values - List of properties with updated values.
* @param {object} values.property - Property specifications.
* @param {number} values.property.id - The updated BACNET property id.
* @param {number} values.property.index - The array index of the updated property.
* @param {object[]} values.value - A list of updated values.
* @param {ApplicationTags} values.value.type - The data-type of the updated value.
* @param {object} values.value.value - The actual updated value.
* @param {number} values.priority - The priority of the updated property.
* @param {function} next - The callback containing an error, in case of a failure and value object in case of success.
* @example
* const bacnet = require('bacstack');
* const client = new bacnet();
*
* client.confirmedCOVNotification(
* '127.0.0.1',
* 3,
* 433,
* {type: 2, instance: 122},
* 120,
* [
* {
* property: {id: 85},
* value: [{type: baEnum.ApplicationTags.REAL, value: 12.3}]
* },
* {
* property: {id: 111},
* value: [{type: baEnum.ApplicationTags.BIT_STRING, value: 0xFFFF}]
* }
* ],
* (err, value) => {
* console.log('value: ', value);
* next();
* });
*/
confirmedCOVNotification(address, subscriberProcessId, initiatingDeviceId, monitoredObjectId, timeRemaining, values, options, next) {
next = next || options;
const settings = {
maxSegments: options.maxSegments || baEnum.MaxSegmentsAccepted.SEGMENTS_65,
maxApdu: options.maxApdu || baEnum.MaxApduLengthAccepted.OCTETS_1476,
invokeId: options.invokeId || this._getInvokeId()
};
const buffer = this._getBuffer();
baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address);
baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.CONFIRMED_COV_NOTIFICATION, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
baServices.covNotify.encode(buffer, subscriberProcessId, initiatingDeviceId, monitoredObjectId, timeRemaining, values);
baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
this._transport.send(buffer.buffer, buffer.offset, address);
this._addCallback(settings.invokeId, (err, data) => {
if (err) return next(err);
next();
});
}

createObject(address, objectId, values, options, next) {
next = next || options;
const settings = {
Expand Down
29 changes: 29 additions & 0 deletions test/integration/confirmed-cov-notification.spec.js
@@ -0,0 +1,29 @@
'use strict';

const expect = require('chai').expect;
const utils = require('./utils');
const baEnum = require('../../lib/enum');

describe('bacstack - confirmedCOVNotification integration', () => {
it('should return a timeout error if no device is available', (next) => {
const client = new utils.bacnetClient({apduTimeout: 200});
client.confirmedCOVNotification(
'127.0.0.1', 3, 433, {type: 2, instance: 122}, 120,
[
{
property: {id: 85},
value: [{type: baEnum.ApplicationTags.REAL, value: 12.3}]
},
{
property: {id: 111},
value: [{type: baEnum.ApplicationTags.BIT_STRING, value: 0xFFFF}]
}
],
(err, value) => {
expect(err.message).to.eql('ERR_TIMEOUT');
expect(value).to.eql(undefined);
client.close();
next();
});
});
});
24 changes: 24 additions & 0 deletions test/integration/unconfirmed-cov-notification.spec.js
@@ -0,0 +1,24 @@
'use strict';

const expect = require('chai').expect;
const utils = require('./utils');
const baEnum = require('../../lib/enum');

describe('bacstack - unconfirmedCOVNotification integration', () => {
it('should correctly send a telegram', () => {
const client = new utils.bacnetClient({apduTimeout: 200});
client.unconfirmedCOVNotification(
'127.0.0.1', 3, 433, {type: 2, instance: 122}, 120, [
{
property: {id: 85},
value: [{type: baEnum.ApplicationTags.REAL, value: 12.3}]
},
{
property: {id: 111},
value:
[{type: baEnum.ApplicationTags.BIT_STRING, value: 0xFFFF}]
}
]);
client.close();
});
});

0 comments on commit a12bb30

Please sign in to comment.