@bitpoolos/edge-bacnet 1.1.7 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bacnet_client.js +331 -168
- package/bacnet_device.js +50 -16
- package/bacnet_gateway.html +119 -15
- package/bacnet_gateway.js +388 -395
- package/bacnet_read.html +32 -11
- package/bacnet_read.js +1 -1
- package/bacnet_server.js +86 -24
- package/common.js +26 -19
- package/examples/1-Discover-Read.json +1 -1
- package/examples/2-Discover-Write.json +1 -1
- package/examples/3-Discover-Read-Write.json +1 -1
- package/package.json +3 -3
- package/resources/{node-bacnet/LICENSE.md → node-bacstack-ts/LICENSE} +3 -4
- package/resources/node-bacstack-ts/README.md +75 -0
- package/resources/{node-bacnet → node-bacstack-ts/dist}/index.js +0 -2
- package/resources/node-bacstack-ts/dist/lib/apdu.js +193 -0
- package/resources/node-bacstack-ts/dist/lib/asn1.js +1660 -0
- package/resources/node-bacstack-ts/dist/lib/bvlc.js +47 -0
- package/resources/node-bacstack-ts/dist/lib/client.js +1454 -0
- package/resources/node-bacstack-ts/dist/lib/enum.js +2114 -0
- package/resources/node-bacstack-ts/dist/lib/npdu.js +112 -0
- package/resources/node-bacstack-ts/dist/lib/services/add-list-element.js +58 -0
- package/resources/node-bacstack-ts/dist/lib/services/alarm-acknowledge.js +93 -0
- package/resources/node-bacstack-ts/dist/lib/services/alarm-summary.js +42 -0
- package/resources/node-bacstack-ts/dist/lib/services/atomic-read-file.js +157 -0
- package/resources/node-bacstack-ts/dist/lib/services/atomic-write-file.js +136 -0
- package/resources/node-bacstack-ts/dist/lib/services/cov-notify.js +119 -0
- package/resources/node-bacstack-ts/dist/lib/services/create-object.js +104 -0
- package/resources/node-bacstack-ts/dist/lib/services/delete-object.js +21 -0
- package/resources/node-bacstack-ts/dist/lib/services/device-communication-control.js +46 -0
- package/resources/node-bacstack-ts/dist/lib/services/error.js +27 -0
- package/resources/node-bacstack-ts/dist/lib/services/event-information.js +100 -0
- package/resources/node-bacstack-ts/dist/lib/services/event-notify-data.js +219 -0
- package/resources/node-bacstack-ts/dist/lib/services/get-enrollment-summary.js +172 -0
- package/resources/node-bacstack-ts/dist/lib/services/get-event-information.js +135 -0
- package/resources/node-bacstack-ts/dist/lib/services/i-am-broadcast.js +59 -0
- package/resources/node-bacstack-ts/dist/lib/services/i-have-broadcast.js +34 -0
- package/resources/node-bacstack-ts/dist/lib/services/index.js +32 -0
- package/resources/node-bacstack-ts/dist/lib/services/life-safety-operation.js +40 -0
- package/resources/node-bacstack-ts/dist/lib/services/private-transfer.js +43 -0
- package/resources/node-bacstack-ts/dist/lib/services/read-property-multiple.js +44 -0
- package/resources/node-bacstack-ts/dist/lib/services/read-property.js +122 -0
- package/resources/node-bacstack-ts/dist/lib/services/read-range.js +201 -0
- package/resources/node-bacstack-ts/dist/lib/services/reinitialize-device.js +35 -0
- package/resources/node-bacstack-ts/dist/lib/services/subscribe-cov.js +55 -0
- package/resources/node-bacstack-ts/dist/lib/services/subscribe-property.js +93 -0
- package/resources/node-bacstack-ts/dist/lib/services/time-sync.js +31 -0
- package/resources/node-bacstack-ts/dist/lib/services/who-has.js +56 -0
- package/resources/node-bacstack-ts/dist/lib/services/who-is.js +45 -0
- package/resources/node-bacstack-ts/dist/lib/services/write-property-multiple.js +105 -0
- package/resources/node-bacstack-ts/dist/lib/services/write-property.js +90 -0
- package/resources/node-bacstack-ts/dist/lib/transport.js +49 -0
- package/resources/node-bacstack-ts/dist/lib/types.js +2 -0
- package/resources/node-bacstack-ts/package.json +94 -0
- package/resources/node-bacnet/CHANGELOG.md +0 -481
- package/resources/node-bacnet/README.md +0 -91
- package/resources/node-bacnet/docs/Client.html +0 -4422
- package/resources/node-bacnet/docs/bacnet-icon-quad.png +0 -0
- package/resources/node-bacnet/docs/bacnet-icon-quad128.png +0 -0
- package/resources/node-bacnet/docs/bacnet-icon-quad64.png +0 -0
- package/resources/node-bacnet/docs/bacnet-icon-small.xcf +0 -0
- package/resources/node-bacnet/docs/bacnet-icon.xcf +0 -0
- package/resources/node-bacnet/docs/bacnet.html +0 -7032
- package/resources/node-bacnet/docs/client.js.html +0 -1759
- package/resources/node-bacnet/docs/enum.js.html +0 -2530
- package/resources/node-bacnet/docs/global.html +0 -2068
- package/resources/node-bacnet/docs/images/mocha-logo.svg +0 -65
- package/resources/node-bacnet/docs/index.html +0 -283
- package/resources/node-bacnet/docs/scripts/collapse.js +0 -11
- package/resources/node-bacnet/docs/scripts/jquery-3.1.1.min.js +0 -4
- package/resources/node-bacnet/docs/scripts/linenumber.js +0 -26
- package/resources/node-bacnet/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/resources/node-bacnet/docs/scripts/prettify/lang-css.js +0 -2
- package/resources/node-bacnet/docs/scripts/prettify/prettify.js +0 -28
- package/resources/node-bacnet/docs/scripts/search.js +0 -47
- package/resources/node-bacnet/docs/services_i-am.js.html +0 -157
- package/resources/node-bacnet/docs/services_time-sync.js.html +0 -118
- package/resources/node-bacnet/docs/services_who-is.js.html +0 -138
- package/resources/node-bacnet/docs/styles/jsdoc.css +0 -683
- package/resources/node-bacnet/docs/styles/prettify.css +0 -82
- package/resources/node-bacnet/examples/discover-devices.js +0 -66
- package/resources/node-bacnet/examples/read-device.js +0 -510
- package/resources/node-bacnet/examples/subscribe-cov.js +0 -75
- package/resources/node-bacnet/lib/apdu.js +0 -209
- package/resources/node-bacnet/lib/asn1.js +0 -1733
- package/resources/node-bacnet/lib/bvlc.js +0 -90
- package/resources/node-bacnet/lib/client.js +0 -1695
- package/resources/node-bacnet/lib/enum.js +0 -2463
- package/resources/node-bacnet/lib/npdu.js +0 -123
- package/resources/node-bacnet/lib/services/add-list-element.js +0 -64
- package/resources/node-bacnet/lib/services/alarm-acknowledge.js +0 -90
- package/resources/node-bacnet/lib/services/alarm-summary.js +0 -42
- package/resources/node-bacnet/lib/services/atomic-read-file.js +0 -162
- package/resources/node-bacnet/lib/services/atomic-write-file.js +0 -138
- package/resources/node-bacnet/lib/services/cov-notify.js +0 -126
- package/resources/node-bacnet/lib/services/create-object.js +0 -106
- package/resources/node-bacnet/lib/services/delete-object.js +0 -23
- package/resources/node-bacnet/lib/services/device-communication-control.js +0 -48
- package/resources/node-bacnet/lib/services/error.js +0 -33
- package/resources/node-bacnet/lib/services/event-information.js +0 -99
- package/resources/node-bacnet/lib/services/event-notify-data.js +0 -229
- package/resources/node-bacnet/lib/services/get-enrollment-summary.js +0 -178
- package/resources/node-bacnet/lib/services/get-event-information.js +0 -144
- package/resources/node-bacnet/lib/services/i-am.js +0 -90
- package/resources/node-bacnet/lib/services/i-have.js +0 -34
- package/resources/node-bacnet/lib/services/index.js +0 -34
- package/resources/node-bacnet/lib/services/life-safety-operation.js +0 -40
- package/resources/node-bacnet/lib/services/private-transfer.js +0 -43
- package/resources/node-bacnet/lib/services/read-property-multiple.js +0 -50
- package/resources/node-bacnet/lib/services/read-property.js +0 -130
- package/resources/node-bacnet/lib/services/read-range.js +0 -201
- package/resources/node-bacnet/lib/services/register-foreign-device.js +0 -18
- package/resources/node-bacnet/lib/services/reinitialize-device.js +0 -37
- package/resources/node-bacnet/lib/services/subscribe-cov.js +0 -57
- package/resources/node-bacnet/lib/services/subscribe-property.js +0 -97
- package/resources/node-bacnet/lib/services/time-sync.js +0 -51
- package/resources/node-bacnet/lib/services/who-has.js +0 -54
- package/resources/node-bacnet/lib/services/who-is.js +0 -71
- package/resources/node-bacnet/lib/services/write-property-multiple.js +0 -117
- package/resources/node-bacnet/lib/services/write-property.js +0 -94
- package/resources/node-bacnet/lib/transport.js +0 -82
- package/resources/node-bacnet/package.json +0 -92
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */
|
|
2
|
-
|
|
3
|
-
.pln {
|
|
4
|
-
color: #1b1918;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/* string content */
|
|
8
|
-
.str {
|
|
9
|
-
color: #7b9726;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/* a keyword */
|
|
13
|
-
.kwd {
|
|
14
|
-
color: #6666ea;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/* a comment */
|
|
18
|
-
.com {
|
|
19
|
-
color: #9c9491;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/* a type name */
|
|
23
|
-
.typ {
|
|
24
|
-
color: #407ee7;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/* a literal value */
|
|
28
|
-
.lit {
|
|
29
|
-
color: #df5320;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* punctuation */
|
|
33
|
-
.pun {
|
|
34
|
-
color: #1b1918;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* lisp open bracket */
|
|
38
|
-
.opn {
|
|
39
|
-
color: #1b1918;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/* lisp close bracket */
|
|
43
|
-
.clo {
|
|
44
|
-
color: #1b1918;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/* a markup tag name */
|
|
48
|
-
.tag {
|
|
49
|
-
color: #f22c40;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/* a markup attribute name */
|
|
53
|
-
.atn {
|
|
54
|
-
color: #df5320;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/* a markup attribute value */
|
|
58
|
-
.atv {
|
|
59
|
-
color: #3d97b8;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* a declaration */
|
|
63
|
-
.dec {
|
|
64
|
-
color: #df5320;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/* a variable name */
|
|
68
|
-
.var {
|
|
69
|
-
color: #f22c40;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* a function name */
|
|
73
|
-
.fun {
|
|
74
|
-
color: #407ee7;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/* Specify class=linenums on a pre to get line numbering */
|
|
78
|
-
ol.linenums {
|
|
79
|
-
margin-top: 0;
|
|
80
|
-
margin-bottom: 0;
|
|
81
|
-
color: #9c9491;
|
|
82
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This script will discover all devices in the network and print out their names
|
|
5
|
-
*
|
|
6
|
-
* After 30s the discovery is stopped automatically
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const Bacnet = require('../index');
|
|
10
|
-
|
|
11
|
-
// create instance of Bacnet
|
|
12
|
-
const bacnetClient = new Bacnet({apduTimeout: 10000, interface: '0.0.0.0'});
|
|
13
|
-
|
|
14
|
-
// emitted on errors
|
|
15
|
-
bacnetClient.on('error', (err) => {
|
|
16
|
-
console.error(err);
|
|
17
|
-
bacnetClient.close();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// emmitted when Bacnet server listens for incoming UDP packages
|
|
21
|
-
bacnetClient.on('listening', () => {
|
|
22
|
-
console.log('discovering devices for 30 seconds ...');
|
|
23
|
-
// discover devices once we are listening
|
|
24
|
-
bacnetClient.whoIs();
|
|
25
|
-
|
|
26
|
-
setTimeout(() => {
|
|
27
|
-
bacnetClient.close();
|
|
28
|
-
console.log('closed transport ' + Date.now());
|
|
29
|
-
}, 30000);
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const knownDevices = [];
|
|
34
|
-
|
|
35
|
-
// emitted when a new device is discovered in the network
|
|
36
|
-
bacnetClient.on('iAm', (device) => {
|
|
37
|
-
// address object of discovered device,
|
|
38
|
-
// just use in subsequent calls that are directed to this device
|
|
39
|
-
const address = device.header.sender;
|
|
40
|
-
|
|
41
|
-
//discovered device ID
|
|
42
|
-
const deviceId = device.payload.deviceId;
|
|
43
|
-
if (knownDevices.includes(deviceId)) return;
|
|
44
|
-
|
|
45
|
-
bacnetClient.readProperty(address, {type: 8, instance: deviceId}, Bacnet.enum.PropertyIdentifier.OBJECT_NAME, (err, value) => {
|
|
46
|
-
if (err) {
|
|
47
|
-
console.log('Found Device ' + deviceId + ' on ' + JSON.stringify(address));
|
|
48
|
-
console.log(err);
|
|
49
|
-
} else {
|
|
50
|
-
bacnetClient.readProperty(address, {type: 8, instance: deviceId}, Bacnet.enum.PropertyIdentifier.OBJECT_NAME, (err2, valueVendor) => {
|
|
51
|
-
|
|
52
|
-
if (value && value.values && value.values[0].value) {
|
|
53
|
-
console.log('Found Device ' + deviceId + ' on ' + JSON.stringify(address) + ': ' + value.values[0].value);
|
|
54
|
-
} else {
|
|
55
|
-
console.log('Found Device ' + deviceId + ' on ' + JSON.stringify(address));
|
|
56
|
-
console.log('value: ', JSON.stringify(value));
|
|
57
|
-
}
|
|
58
|
-
if (!err2 && valueVendor && valueVendor.values && valueVendor.values[0].value) {
|
|
59
|
-
console.log('Vendor: ' + valueVendor.values[0].value);
|
|
60
|
-
}
|
|
61
|
-
console.log();
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
knownDevices.push(deviceId);
|
|
66
|
-
});
|
|
@@ -1,510 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This script will discover all devices in the network and read out all
|
|
5
|
-
* properties and deliver a JSON as device description
|
|
6
|
-
*
|
|
7
|
-
* If a deviceId is given as first parameter then only this device is discovered
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const Bacnet = require('../index');
|
|
11
|
-
const process = require('process');
|
|
12
|
-
|
|
13
|
-
// Map the Property types to their enums/bitstrings
|
|
14
|
-
const PropertyIdentifierToEnumMap = {};
|
|
15
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.OBJECT_TYPE] = Bacnet.enum.ObjectType;
|
|
16
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.SEGMENTATION_SUPPORTED] = Bacnet.enum.Segmentation;
|
|
17
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.EVENT_STATE] = Bacnet.enum.EventState;
|
|
18
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.UNITS] = Bacnet.enum.EngineeringUnits;
|
|
19
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.RELIABILITY] = Bacnet.enum.Reliability;
|
|
20
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.NOTIFY_TYPE] = Bacnet.enum.NotifyType;
|
|
21
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.POLARITY] = Bacnet.enum.Polarity;
|
|
22
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED] = Bacnet.enum.ServicesSupported;
|
|
23
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED] = Bacnet.enum.ObjectTypesSupported;
|
|
24
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.STATUS_FLAGS] = Bacnet.enum.StatusFlags;
|
|
25
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.LIMIT_ENABLE] = Bacnet.enum.LimitEnable;
|
|
26
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.EVENT_ENABLE] = Bacnet.enum.EventTransitionBits;
|
|
27
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.ACKED_TRANSITIONS] = Bacnet.enum.EventTransitionBits;
|
|
28
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.SYSTEM_STATUS] = Bacnet.enum.DeviceStatus;
|
|
29
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.SYSTEM_STATUS] = Bacnet.enum.DeviceStatus;
|
|
30
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.ACK_REQUIRED] = Bacnet.enum.EventTransitionBits;
|
|
31
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.LOGGING_TYPE] = Bacnet.enum.LoggingType;
|
|
32
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.FILE_ACCESS_METHOD] = Bacnet.enum.FileAccessMethod;
|
|
33
|
-
PropertyIdentifierToEnumMap[Bacnet.enum.PropertyIdentifier.NODE_TYPE] = Bacnet.enum.NodeType;
|
|
34
|
-
|
|
35
|
-
// Sometimes the Map needs to be more specific
|
|
36
|
-
const ObjectTypeSpecificPropertyIdentifierToEnumMap = {};
|
|
37
|
-
|
|
38
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_INPUT] = {};
|
|
39
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_INPUT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV;
|
|
40
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_INPUT][Bacnet.enum.PropertyIdentifier.MODE] = Bacnet.enum.BinaryPV;
|
|
41
|
-
|
|
42
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.ANALOG_INPUT] = {};
|
|
43
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.ANALOG_INPUT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV; //????
|
|
44
|
-
|
|
45
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.ANALOG_OUTPUT] = {};
|
|
46
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.ANALOG_OUTPUT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV; //????
|
|
47
|
-
|
|
48
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_OUTPUT] = {};
|
|
49
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_OUTPUT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV;
|
|
50
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_OUTPUT][Bacnet.enum.PropertyIdentifier.RELINQUISH_DEFAULT] = Bacnet.enum.BinaryPV;
|
|
51
|
-
|
|
52
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_VALUE] = {};
|
|
53
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_VALUE][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV;
|
|
54
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_VALUE][Bacnet.enum.PropertyIdentifier.RELINQUISH_DEFAULT] = Bacnet.enum.BinaryPV;
|
|
55
|
-
|
|
56
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_LIGHTING_OUTPUT] = {};
|
|
57
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_LIGHTING_OUTPUT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryLightingPV;
|
|
58
|
-
|
|
59
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BITSTRING_VALUE] = {};
|
|
60
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.BINARY_VALUE][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.BinaryPV; // ???
|
|
61
|
-
|
|
62
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT] = {};
|
|
63
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.LifeSafetyState;
|
|
64
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.TRACKING_VALUE] = Bacnet.enum.LifeSafetyState;
|
|
65
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.MODE] = Bacnet.enum.LifeSafetyMode;
|
|
66
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.ACCEPTED_MODES] = Bacnet.enum.LifeSafetyMode;
|
|
67
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.SILENCED] = Bacnet.enum.LifeSafetyState;
|
|
68
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_POINT][Bacnet.enum.PropertyIdentifier.OPERATION_EXPECTED] = Bacnet.enum.LifeSafetyOperation;
|
|
69
|
-
|
|
70
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_ZONE] = {};
|
|
71
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_ZONE][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.LifeSafetyState;
|
|
72
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LIFE_SAFETY_ZONE][Bacnet.enum.PropertyIdentifier.MODE] = Bacnet.enum.LifeSafetyMode;
|
|
73
|
-
|
|
74
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LOAD_CONTROL] = {};
|
|
75
|
-
ObjectTypeSpecificPropertyIdentifierToEnumMap[Bacnet.enum.ObjectType.LOAD_CONTROL][Bacnet.enum.PropertyIdentifier.PRESENT_VALUE] = Bacnet.enum.ShedState;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// For Objects we read out All properties if cli parameter --all is provided
|
|
79
|
-
const propSubSet = (process.argv.includes('--all')) ? Object.values(Bacnet.enum.PropertyIdentifier) : [
|
|
80
|
-
/* normally supported from all devices */
|
|
81
|
-
Bacnet.enum.PropertyIdentifier.OBJECT_IDENTIFIER,
|
|
82
|
-
Bacnet.enum.PropertyIdentifier.OBJECT_NAME,
|
|
83
|
-
Bacnet.enum.PropertyIdentifier.OBJECT_TYPE,
|
|
84
|
-
Bacnet.enum.PropertyIdentifier.PRESENT_VALUE,
|
|
85
|
-
Bacnet.enum.PropertyIdentifier.STATUS_FLAGS,
|
|
86
|
-
Bacnet.enum.PropertyIdentifier.EVENT_STATE,
|
|
87
|
-
Bacnet.enum.PropertyIdentifier.RELIABILITY,
|
|
88
|
-
Bacnet.enum.PropertyIdentifier.OUT_OF_SERVICE,
|
|
89
|
-
Bacnet.enum.PropertyIdentifier.UNITS,
|
|
90
|
-
/* other properties */
|
|
91
|
-
Bacnet.enum.PropertyIdentifier.DESCRIPTION,
|
|
92
|
-
Bacnet.enum.PropertyIdentifier.SYSTEM_STATUS,
|
|
93
|
-
Bacnet.enum.PropertyIdentifier.VENDOR_NAME,
|
|
94
|
-
Bacnet.enum.PropertyIdentifier.VENDOR_IDENTIFIER,
|
|
95
|
-
Bacnet.enum.PropertyIdentifier.MODEL_NAME,
|
|
96
|
-
Bacnet.enum.PropertyIdentifier.FIRMWARE_REVISION,
|
|
97
|
-
Bacnet.enum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION,
|
|
98
|
-
Bacnet.enum.PropertyIdentifier.LOCATION,
|
|
99
|
-
Bacnet.enum.PropertyIdentifier.LOCAL_DATE,
|
|
100
|
-
Bacnet.enum.PropertyIdentifier.LOCAL_TIME,
|
|
101
|
-
Bacnet.enum.PropertyIdentifier.UTC_OFFSET,
|
|
102
|
-
Bacnet.enum.PropertyIdentifier.DAYLIGHT_SAVINGS_STATUS,
|
|
103
|
-
Bacnet.enum.PropertyIdentifier.PROTOCOL_VERSION,
|
|
104
|
-
Bacnet.enum.PropertyIdentifier.PROTOCOL_REVISION,
|
|
105
|
-
Bacnet.enum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED,
|
|
106
|
-
Bacnet.enum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED,
|
|
107
|
-
Bacnet.enum.PropertyIdentifier.OBJECT_LIST,
|
|
108
|
-
Bacnet.enum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED,
|
|
109
|
-
Bacnet.enum.PropertyIdentifier.SEGMENTATION_SUPPORTED,
|
|
110
|
-
Bacnet.enum.PropertyIdentifier.APDU_TIMEOUT,
|
|
111
|
-
Bacnet.enum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES,
|
|
112
|
-
Bacnet.enum.PropertyIdentifier.DEVICE_ADDRESS_BINDING,
|
|
113
|
-
Bacnet.enum.PropertyIdentifier.DATABASE_REVISION,
|
|
114
|
-
Bacnet.enum.PropertyIdentifier.MAX_INFO_FRAMES,
|
|
115
|
-
Bacnet.enum.PropertyIdentifier.MAX_MASTER,
|
|
116
|
-
Bacnet.enum.PropertyIdentifier.ACTIVE_COV_SUBSCRIPTIONS,
|
|
117
|
-
Bacnet.enum.PropertyIdentifier.ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS
|
|
118
|
-
];
|
|
119
|
-
const debug = process.argv.includes('--debug');
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Retrieve all properties manually because ReadPropertyMultiple is not available
|
|
123
|
-
* @param address
|
|
124
|
-
* @param objectId
|
|
125
|
-
* @param callback
|
|
126
|
-
* @param propList
|
|
127
|
-
* @param result
|
|
128
|
-
* @returns {*}
|
|
129
|
-
*/
|
|
130
|
-
function getAllPropertiesManually(address, objectId, callback, propList, result) {
|
|
131
|
-
if (!propList) {
|
|
132
|
-
propList = propSubSet.map((x) => x); // Clone the array
|
|
133
|
-
}
|
|
134
|
-
if (!result) {
|
|
135
|
-
result = [];
|
|
136
|
-
}
|
|
137
|
-
if (!propList.length) {
|
|
138
|
-
return callback({
|
|
139
|
-
values: [
|
|
140
|
-
{
|
|
141
|
-
objectId: objectId,
|
|
142
|
-
values: result
|
|
143
|
-
}
|
|
144
|
-
]
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const prop = propList.shift();
|
|
149
|
-
|
|
150
|
-
// Read only object-list property
|
|
151
|
-
bacnetClient.readProperty(address, objectId, prop, (err, value) => {
|
|
152
|
-
if (!err) {
|
|
153
|
-
if (debug) {
|
|
154
|
-
console.log('Handle value ' + prop + ': ', JSON.stringify(value));
|
|
155
|
-
}
|
|
156
|
-
const objRes = value.property;
|
|
157
|
-
objRes.value = value.values;
|
|
158
|
-
result.push(objRes);
|
|
159
|
-
} else {
|
|
160
|
-
// console.log('Device do not contain object ' + Bacnet.enum.getEnumName(Bacnet.enum.PropertyIdentifier, prop));
|
|
161
|
-
}
|
|
162
|
-
getAllPropertiesManually(address, objectId, callback, propList, result);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Reads ou one bit out of an buffer
|
|
169
|
-
* @param buffer
|
|
170
|
-
* @param i
|
|
171
|
-
* @param bit
|
|
172
|
-
* @returns {number}
|
|
173
|
-
*/
|
|
174
|
-
function readBit(buffer, i, bit) {
|
|
175
|
-
return (buffer[i] >> bit) % 2;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* sets a bit in a buffer
|
|
180
|
-
* @param buffer
|
|
181
|
-
* @param i
|
|
182
|
-
* @param bit
|
|
183
|
-
* @param value
|
|
184
|
-
*/
|
|
185
|
-
function setBit(buffer, i, bit, value) {
|
|
186
|
-
if (value === 0) {
|
|
187
|
-
buffer[i] &= ~(1 << bit);
|
|
188
|
-
} else {
|
|
189
|
-
buffer[i] |= (1 << bit);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Parses a Bitstring and returns array with all true values
|
|
195
|
-
* @param buffer
|
|
196
|
-
* @param bitsUsed
|
|
197
|
-
* @param usedEnum
|
|
198
|
-
* @returns {[]}
|
|
199
|
-
*/
|
|
200
|
-
function handleBitString(buffer, bitsUsed, usedEnum) {
|
|
201
|
-
const res = [];
|
|
202
|
-
for (let i = 0; i < bitsUsed; i++) {
|
|
203
|
-
const bufferIndex = Math.floor(i / 8);
|
|
204
|
-
if (readBit(buffer, bufferIndex, i % 8)) {
|
|
205
|
-
res.push(Bacnet.enum.getEnumName(usedEnum, i));
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return res;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Parses a property value
|
|
213
|
-
* @param address
|
|
214
|
-
* @param objId
|
|
215
|
-
* @param parentType
|
|
216
|
-
* @param value
|
|
217
|
-
* @param supportsMultiple
|
|
218
|
-
* @param callback
|
|
219
|
-
*/
|
|
220
|
-
function parseValue(address, objId, parentType, value, supportsMultiple, callback) {
|
|
221
|
-
let resValue = null;
|
|
222
|
-
if (value && value.type && value.value !== null && value.value !== undefined) {
|
|
223
|
-
switch (value.type) {
|
|
224
|
-
case Bacnet.enum.ApplicationTag.NULL:
|
|
225
|
-
// should be null already, but set again
|
|
226
|
-
resValue = null;
|
|
227
|
-
break;
|
|
228
|
-
case Bacnet.enum.ApplicationTag.BOOLEAN:
|
|
229
|
-
// convert number to a real boolean
|
|
230
|
-
resValue = !!value.value;
|
|
231
|
-
break;
|
|
232
|
-
case Bacnet.enum.ApplicationTag.UNSIGNED_INTEGER:
|
|
233
|
-
case Bacnet.enum.ApplicationTag.SIGNED_INTEGER:
|
|
234
|
-
case Bacnet.enum.ApplicationTag.REAL:
|
|
235
|
-
case Bacnet.enum.ApplicationTag.DOUBLE:
|
|
236
|
-
case Bacnet.enum.ApplicationTag.CHARACTER_STRING:
|
|
237
|
-
// datatype should be correct already
|
|
238
|
-
resValue = value.value;
|
|
239
|
-
break;
|
|
240
|
-
case Bacnet.enum.ApplicationTag.DATE:
|
|
241
|
-
case Bacnet.enum.ApplicationTag.TIME:
|
|
242
|
-
case Bacnet.enum.ApplicationTag.TIMESTAMP:
|
|
243
|
-
// datatype should be Date too
|
|
244
|
-
// Javascript do not have date/timestamp only
|
|
245
|
-
resValue = value.value;
|
|
246
|
-
break;
|
|
247
|
-
case Bacnet.enum.ApplicationTag.BIT_STRING:
|
|
248
|
-
// handle bitstrings specific and more generic
|
|
249
|
-
if (ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType] && ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType][objId]) {
|
|
250
|
-
resValue = handleBitString(value.value.value, value.value.bitsUsed, ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType][objId]);
|
|
251
|
-
} else if (PropertyIdentifierToEnumMap[objId]) {
|
|
252
|
-
resValue = handleBitString(value.value.value, value.value.bitsUsed, PropertyIdentifierToEnumMap[objId]);
|
|
253
|
-
} else {
|
|
254
|
-
if (parentType !== Bacnet.enum.ObjectType.BITSTRING_VALUE) {
|
|
255
|
-
console.log('Unknown value for BIT_STRING type for objId ' + Bacnet.enum.getEnumName(Bacnet.enum.PropertyIdentifier, objId) + ' and parent type ' + Bacnet.enum.getEnumName(Bacnet.enum.ObjectType, parentType));
|
|
256
|
-
}
|
|
257
|
-
resValue = value.value;
|
|
258
|
-
}
|
|
259
|
-
break;
|
|
260
|
-
case Bacnet.enum.ApplicationTag.ENUMERATED:
|
|
261
|
-
// handle enumerations specific and more generic
|
|
262
|
-
if (ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType] && ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType][objId]) {
|
|
263
|
-
resValue = Bacnet.enum.getEnumName(ObjectTypeSpecificPropertyIdentifierToEnumMap[parentType][objId], value.value);
|
|
264
|
-
} else if (PropertyIdentifierToEnumMap[objId]) {
|
|
265
|
-
resValue = Bacnet.enum.getEnumName(PropertyIdentifierToEnumMap[objId], value.value);
|
|
266
|
-
} else {
|
|
267
|
-
console.log('Unknown value for ENUMERATED type for objId ' + Bacnet.enum.getEnumName(Bacnet.enum.PropertyIdentifier, objId) + ' and parent type ' + Bacnet.enum.getEnumName(Bacnet.enum.ObjectType, parentType));
|
|
268
|
-
resValue = value.value;
|
|
269
|
-
}
|
|
270
|
-
break;
|
|
271
|
-
case Bacnet.enum.ApplicationTag.OBJECTIDENTIFIER:
|
|
272
|
-
// Look up object identifiers
|
|
273
|
-
// Some object identifiers should not be looked up because we end in loops else
|
|
274
|
-
if (objId === Bacnet.enum.PropertyIdentifier.OBJECT_IDENTIFIER || objId === Bacnet.enum.PropertyIdentifier.STRUCTURED_OBJECT_LIST || objId === Bacnet.enum.PropertyIdentifier.SUBORDINATE_LIST) {
|
|
275
|
-
resValue = value.value;
|
|
276
|
-
} else if (supportsMultiple) {
|
|
277
|
-
const requestArray = [{
|
|
278
|
-
objectId: value.value,
|
|
279
|
-
properties: [{id: 8}]
|
|
280
|
-
}];
|
|
281
|
-
bacnetClient.readPropertyMultiple(address, requestArray, (err, resValue) => {
|
|
282
|
-
//console.log(JSON.stringify(value.value) + ': ' + JSON.stringify(resValue));
|
|
283
|
-
parseDeviceObject(address, resValue, value.value, true, callback);
|
|
284
|
-
});
|
|
285
|
-
return;
|
|
286
|
-
} else {
|
|
287
|
-
getAllPropertiesManually(address, value.value, result => {
|
|
288
|
-
parseDeviceObject(address, result, value.value, false, callback);
|
|
289
|
-
});
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
break;
|
|
293
|
-
case Bacnet.enum.ApplicationTag.OCTET_STRING:
|
|
294
|
-
// It is kind of binary data??
|
|
295
|
-
resValue = value.value;
|
|
296
|
-
break;
|
|
297
|
-
case Bacnet.enum.ApplicationTag.ERROR:
|
|
298
|
-
// lookup error class and code
|
|
299
|
-
resValue = {
|
|
300
|
-
errorClass: Bacnet.enum.getEnumName(Bacnet.enum.ErrorClass, value.value.errorClass),
|
|
301
|
-
errorCode: Bacnet.enum.getEnumName(Bacnet.enum.ErrorCode, value.value.errorCode)
|
|
302
|
-
};
|
|
303
|
-
break;
|
|
304
|
-
case Bacnet.enum.ApplicationTag.OBJECT_PROPERTY_REFERENCE:
|
|
305
|
-
case Bacnet.enum.ApplicationTag.DEVICE_OBJECT_PROPERTY_REFERENCE:
|
|
306
|
-
case Bacnet.enum.ApplicationTag.DEVICE_OBJECT_REFERENCE:
|
|
307
|
-
case Bacnet.enum.ApplicationTag.READ_ACCESS_SPECIFICATION: //???
|
|
308
|
-
resValue = value.value;
|
|
309
|
-
break;
|
|
310
|
-
case Bacnet.enum.ApplicationTag.CONTEXT_SPECIFIC_DECODED:
|
|
311
|
-
parseValue(address, objId, parentType, value.value, supportsMultiple, callback);
|
|
312
|
-
return;
|
|
313
|
-
case Bacnet.enum.ApplicationTag.READ_ACCESS_RESULT: // ????
|
|
314
|
-
resValue = value.value;
|
|
315
|
-
break;
|
|
316
|
-
default:
|
|
317
|
-
console.log('unknown type ' + value.type + ': ' + JSON.stringify(value));
|
|
318
|
-
resValue = value;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
setImmediate(() => callback(resValue));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Parse an object structure
|
|
327
|
-
* @param address
|
|
328
|
-
* @param obj
|
|
329
|
-
* @param parent
|
|
330
|
-
* @param supportsMultiple
|
|
331
|
-
* @param callback
|
|
332
|
-
*/
|
|
333
|
-
function parseDeviceObject(address, obj, parent, supportsMultiple, callback) {
|
|
334
|
-
if (debug) {
|
|
335
|
-
console.log('START parseDeviceObject: ' + JSON.stringify(parent) + ' : ' + JSON.stringify(obj));
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
if(!obj) {
|
|
339
|
-
console.log('object not valid on parse device object');
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (!obj.values || !Array.isArray(obj.values)) {
|
|
344
|
-
console.log('No device or invalid response');
|
|
345
|
-
callback({'ERROR': 'No device or invalid response'});
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
let cbCount = 0;
|
|
350
|
-
let objDef = {};
|
|
351
|
-
|
|
352
|
-
const finalize = () => {
|
|
353
|
-
// Normalize and remove single item arrays
|
|
354
|
-
Object.keys(objDef).forEach(devId => {
|
|
355
|
-
Object.keys(objDef[devId]).forEach(objId => {
|
|
356
|
-
if (objDef[devId][objId].length === 1) {
|
|
357
|
-
objDef[devId][objId] = objDef[devId][objId][0];
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
// If (standard case) only one device was in do not create sub structures)
|
|
362
|
-
if (obj.values.length === 1) {
|
|
363
|
-
objDef = objDef[obj.values[0].objectId.instance];
|
|
364
|
-
}
|
|
365
|
-
if (debug) {
|
|
366
|
-
console.log('END parseDeviceObject: ' + JSON.stringify(parent) + ' : ' + JSON.stringify(objDef));
|
|
367
|
-
}
|
|
368
|
-
callback(objDef);
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
obj.values.forEach(devBaseObj => {
|
|
372
|
-
if (!devBaseObj.objectId) {
|
|
373
|
-
console.log('No device Id found in object data');
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
if (devBaseObj.objectId.type === undefined || devBaseObj.objectId.instance === undefined) {
|
|
377
|
-
console.log('No device type or instance found in object data');
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
if (!devBaseObj.values || !Array.isArray(devBaseObj.values)) {
|
|
381
|
-
console.log('No device values response');
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
const deviceId = devBaseObj.objectId.instance;
|
|
385
|
-
objDef[deviceId] = {};
|
|
386
|
-
devBaseObj.values.forEach(devObj => {
|
|
387
|
-
let objId = Bacnet.enum.getEnumName(Bacnet.enum.PropertyIdentifier, devObj.id);
|
|
388
|
-
if (devObj.index !== 4294967295) {
|
|
389
|
-
objId += '-' + devObj.index;
|
|
390
|
-
}
|
|
391
|
-
if (debug) {
|
|
392
|
-
console.log('Handle Object property:', deviceId, objId, devObj.value);
|
|
393
|
-
}
|
|
394
|
-
devObj.value.forEach(val => {
|
|
395
|
-
if (JSON.stringify(val.value) === JSON.stringify(parent)) {
|
|
396
|
-
// ignore parent object
|
|
397
|
-
objDef[deviceId][objId] = objDef[deviceId][objId] || [];
|
|
398
|
-
objDef[deviceId][objId].push(val.value);
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
cbCount++;
|
|
402
|
-
parseValue(address, devObj.id, parent.type, val, supportsMultiple, parsedValue => {
|
|
403
|
-
if (debug) {
|
|
404
|
-
console.log('RETURN parsedValue', deviceId, objId, devObj.value, parsedValue);
|
|
405
|
-
}
|
|
406
|
-
objDef[deviceId][objId] = objDef[deviceId][objId] || [];
|
|
407
|
-
objDef[deviceId][objId].push(parsedValue);
|
|
408
|
-
if (!--cbCount) {
|
|
409
|
-
finalize();
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
});
|
|
416
|
-
if (cbCount === 0) {
|
|
417
|
-
finalize();
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
let objectsDone = 0;
|
|
422
|
-
/**
|
|
423
|
-
* Print result info object
|
|
424
|
-
* @param deviceId
|
|
425
|
-
* @param obj
|
|
426
|
-
*/
|
|
427
|
-
function printResultObject(deviceId, obj) {
|
|
428
|
-
objectsDone++;
|
|
429
|
-
console.log(`Device ${deviceId} (${objectsDone}/${Object.keys(knownDevices).length}) read successfully ...`);
|
|
430
|
-
console.log(JSON.stringify(obj));
|
|
431
|
-
console.log();
|
|
432
|
-
console.log();
|
|
433
|
-
|
|
434
|
-
if (objectsDone === Object.keys(knownDevices).length) {
|
|
435
|
-
setTimeout(() => {
|
|
436
|
-
bacnetClient.close();
|
|
437
|
-
console.log('closed transport ' + Date.now());
|
|
438
|
-
}, 1000);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
let limitToDevice = null;
|
|
443
|
-
if (process.argv.length === 3) {
|
|
444
|
-
limitToDevice = parseInt(process.argv[2]);
|
|
445
|
-
if (isNaN(limitToDevice)) {
|
|
446
|
-
limitToDevice = null;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
// create instance of Bacnet
|
|
450
|
-
const bacnetClient = new Bacnet({apduTimeout: 4000, interface: '0.0.0.0'});
|
|
451
|
-
|
|
452
|
-
// emitted for each new message
|
|
453
|
-
bacnetClient.on('message', (msg, rinfo) => {
|
|
454
|
-
console.log(msg);
|
|
455
|
-
if (rinfo) console.log(rinfo);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
// emitted on errors
|
|
459
|
-
bacnetClient.on('error', (err) => {
|
|
460
|
-
console.error(err);
|
|
461
|
-
bacnetClient.close();
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
// emmitted when Bacnet server listens for incoming UDP packages
|
|
465
|
-
bacnetClient.on('listening', () => {
|
|
466
|
-
console.log('sent whoIs ' + Date.now());
|
|
467
|
-
// discover devices once we are listening
|
|
468
|
-
bacnetClient.whoIs();
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
const knownDevices = [];
|
|
472
|
-
|
|
473
|
-
// emitted when a new device is discovered in the network
|
|
474
|
-
bacnetClient.on('iAm', (device) => {
|
|
475
|
-
// address object of discovered device,
|
|
476
|
-
// just use in subsequent calls that are directed to this device
|
|
477
|
-
const address = device.header.sender;
|
|
478
|
-
|
|
479
|
-
//discovered device ID
|
|
480
|
-
const deviceId = device.payload.deviceId;
|
|
481
|
-
if (knownDevices.includes(deviceId)) return;
|
|
482
|
-
if (limitToDevice !== null && limitToDevice !== deviceId) return;
|
|
483
|
-
|
|
484
|
-
console.log('Found Device ' + deviceId + ' on ' + JSON.stringify(address));
|
|
485
|
-
knownDevices.push(deviceId);
|
|
486
|
-
|
|
487
|
-
const propertyList = [];
|
|
488
|
-
propSubSet.forEach(item => {
|
|
489
|
-
propertyList.push({id: item});
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
const requestArray = [{
|
|
493
|
-
objectId: {type: 8, instance: deviceId},
|
|
494
|
-
properties: propertyList
|
|
495
|
-
}
|
|
496
|
-
];
|
|
497
|
-
|
|
498
|
-
bacnetClient.readPropertyMultiple(address, requestArray, (err, value) => {
|
|
499
|
-
if (err) {
|
|
500
|
-
console.log(deviceId, 'No ReadPropertyMultiple supported:', err.message);
|
|
501
|
-
getAllPropertiesManually(address, {type: 8, instance: deviceId}, result => {
|
|
502
|
-
parseDeviceObject(address, result, {type: 8, instance: deviceId}, false, res => printResultObject(deviceId, res));
|
|
503
|
-
});
|
|
504
|
-
} else {
|
|
505
|
-
console.log(deviceId, 'ReadPropertyMultiple supported ...');
|
|
506
|
-
parseDeviceObject(address, value, {type: 8, instance: deviceId}, true, res => printResultObject(deviceId, res));
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
});
|