@bitpoolos/edge-bacnet 1.1.8 → 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.
Files changed (122) hide show
  1. package/bacnet_client.js +331 -168
  2. package/bacnet_device.js +50 -16
  3. package/bacnet_gateway.html +119 -15
  4. package/bacnet_gateway.js +388 -395
  5. package/bacnet_read.html +32 -11
  6. package/bacnet_read.js +1 -1
  7. package/bacnet_server.js +16 -12
  8. package/common.js +26 -19
  9. package/examples/1-Discover-Read.json +1 -1
  10. package/examples/2-Discover-Write.json +1 -1
  11. package/examples/3-Discover-Read-Write.json +1 -1
  12. package/package.json +3 -3
  13. package/resources/{node-bacnet/LICENSE.md → node-bacstack-ts/LICENSE} +3 -4
  14. package/resources/node-bacstack-ts/README.md +75 -0
  15. package/resources/{node-bacnet → node-bacstack-ts/dist}/index.js +0 -2
  16. package/resources/node-bacstack-ts/dist/lib/apdu.js +193 -0
  17. package/resources/node-bacstack-ts/dist/lib/asn1.js +1660 -0
  18. package/resources/node-bacstack-ts/dist/lib/bvlc.js +47 -0
  19. package/resources/node-bacstack-ts/dist/lib/client.js +1454 -0
  20. package/resources/node-bacstack-ts/dist/lib/enum.js +2114 -0
  21. package/resources/node-bacstack-ts/dist/lib/npdu.js +112 -0
  22. package/resources/node-bacstack-ts/dist/lib/services/add-list-element.js +58 -0
  23. package/resources/node-bacstack-ts/dist/lib/services/alarm-acknowledge.js +93 -0
  24. package/resources/node-bacstack-ts/dist/lib/services/alarm-summary.js +42 -0
  25. package/resources/node-bacstack-ts/dist/lib/services/atomic-read-file.js +157 -0
  26. package/resources/node-bacstack-ts/dist/lib/services/atomic-write-file.js +136 -0
  27. package/resources/node-bacstack-ts/dist/lib/services/cov-notify.js +119 -0
  28. package/resources/node-bacstack-ts/dist/lib/services/create-object.js +104 -0
  29. package/resources/node-bacstack-ts/dist/lib/services/delete-object.js +21 -0
  30. package/resources/node-bacstack-ts/dist/lib/services/device-communication-control.js +46 -0
  31. package/resources/node-bacstack-ts/dist/lib/services/error.js +27 -0
  32. package/resources/node-bacstack-ts/dist/lib/services/event-information.js +100 -0
  33. package/resources/node-bacstack-ts/dist/lib/services/event-notify-data.js +219 -0
  34. package/resources/node-bacstack-ts/dist/lib/services/get-enrollment-summary.js +172 -0
  35. package/resources/node-bacstack-ts/dist/lib/services/get-event-information.js +135 -0
  36. package/resources/node-bacstack-ts/dist/lib/services/i-am-broadcast.js +59 -0
  37. package/resources/node-bacstack-ts/dist/lib/services/i-have-broadcast.js +34 -0
  38. package/resources/node-bacstack-ts/dist/lib/services/index.js +32 -0
  39. package/resources/node-bacstack-ts/dist/lib/services/life-safety-operation.js +40 -0
  40. package/resources/node-bacstack-ts/dist/lib/services/private-transfer.js +43 -0
  41. package/resources/node-bacstack-ts/dist/lib/services/read-property-multiple.js +44 -0
  42. package/resources/node-bacstack-ts/dist/lib/services/read-property.js +122 -0
  43. package/resources/node-bacstack-ts/dist/lib/services/read-range.js +201 -0
  44. package/resources/node-bacstack-ts/dist/lib/services/reinitialize-device.js +35 -0
  45. package/resources/node-bacstack-ts/dist/lib/services/subscribe-cov.js +55 -0
  46. package/resources/node-bacstack-ts/dist/lib/services/subscribe-property.js +93 -0
  47. package/resources/node-bacstack-ts/dist/lib/services/time-sync.js +31 -0
  48. package/resources/node-bacstack-ts/dist/lib/services/who-has.js +56 -0
  49. package/resources/node-bacstack-ts/dist/lib/services/who-is.js +45 -0
  50. package/resources/node-bacstack-ts/dist/lib/services/write-property-multiple.js +105 -0
  51. package/resources/node-bacstack-ts/dist/lib/services/write-property.js +90 -0
  52. package/resources/node-bacstack-ts/dist/lib/transport.js +49 -0
  53. package/resources/node-bacstack-ts/dist/lib/types.js +2 -0
  54. package/resources/node-bacstack-ts/package.json +94 -0
  55. package/resources/node-bacnet/CHANGELOG.md +0 -481
  56. package/resources/node-bacnet/README.md +0 -91
  57. package/resources/node-bacnet/docs/Client.html +0 -4422
  58. package/resources/node-bacnet/docs/bacnet-icon-quad.png +0 -0
  59. package/resources/node-bacnet/docs/bacnet-icon-quad128.png +0 -0
  60. package/resources/node-bacnet/docs/bacnet-icon-quad64.png +0 -0
  61. package/resources/node-bacnet/docs/bacnet-icon-small.xcf +0 -0
  62. package/resources/node-bacnet/docs/bacnet-icon.xcf +0 -0
  63. package/resources/node-bacnet/docs/bacnet.html +0 -7032
  64. package/resources/node-bacnet/docs/client.js.html +0 -1759
  65. package/resources/node-bacnet/docs/enum.js.html +0 -2530
  66. package/resources/node-bacnet/docs/global.html +0 -2068
  67. package/resources/node-bacnet/docs/images/mocha-logo.svg +0 -65
  68. package/resources/node-bacnet/docs/index.html +0 -283
  69. package/resources/node-bacnet/docs/scripts/collapse.js +0 -11
  70. package/resources/node-bacnet/docs/scripts/jquery-3.1.1.min.js +0 -4
  71. package/resources/node-bacnet/docs/scripts/linenumber.js +0 -26
  72. package/resources/node-bacnet/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  73. package/resources/node-bacnet/docs/scripts/prettify/lang-css.js +0 -2
  74. package/resources/node-bacnet/docs/scripts/prettify/prettify.js +0 -28
  75. package/resources/node-bacnet/docs/scripts/search.js +0 -47
  76. package/resources/node-bacnet/docs/services_i-am.js.html +0 -157
  77. package/resources/node-bacnet/docs/services_time-sync.js.html +0 -118
  78. package/resources/node-bacnet/docs/services_who-is.js.html +0 -138
  79. package/resources/node-bacnet/docs/styles/jsdoc.css +0 -683
  80. package/resources/node-bacnet/docs/styles/prettify.css +0 -82
  81. package/resources/node-bacnet/examples/discover-devices.js +0 -66
  82. package/resources/node-bacnet/examples/read-device.js +0 -510
  83. package/resources/node-bacnet/examples/subscribe-cov.js +0 -75
  84. package/resources/node-bacnet/lib/apdu.js +0 -209
  85. package/resources/node-bacnet/lib/asn1.js +0 -1733
  86. package/resources/node-bacnet/lib/bvlc.js +0 -90
  87. package/resources/node-bacnet/lib/client.js +0 -1695
  88. package/resources/node-bacnet/lib/enum.js +0 -2463
  89. package/resources/node-bacnet/lib/npdu.js +0 -123
  90. package/resources/node-bacnet/lib/services/add-list-element.js +0 -64
  91. package/resources/node-bacnet/lib/services/alarm-acknowledge.js +0 -90
  92. package/resources/node-bacnet/lib/services/alarm-summary.js +0 -42
  93. package/resources/node-bacnet/lib/services/atomic-read-file.js +0 -162
  94. package/resources/node-bacnet/lib/services/atomic-write-file.js +0 -138
  95. package/resources/node-bacnet/lib/services/cov-notify.js +0 -126
  96. package/resources/node-bacnet/lib/services/create-object.js +0 -106
  97. package/resources/node-bacnet/lib/services/delete-object.js +0 -23
  98. package/resources/node-bacnet/lib/services/device-communication-control.js +0 -48
  99. package/resources/node-bacnet/lib/services/error.js +0 -33
  100. package/resources/node-bacnet/lib/services/event-information.js +0 -99
  101. package/resources/node-bacnet/lib/services/event-notify-data.js +0 -229
  102. package/resources/node-bacnet/lib/services/get-enrollment-summary.js +0 -178
  103. package/resources/node-bacnet/lib/services/get-event-information.js +0 -144
  104. package/resources/node-bacnet/lib/services/i-am.js +0 -90
  105. package/resources/node-bacnet/lib/services/i-have.js +0 -34
  106. package/resources/node-bacnet/lib/services/index.js +0 -34
  107. package/resources/node-bacnet/lib/services/life-safety-operation.js +0 -40
  108. package/resources/node-bacnet/lib/services/private-transfer.js +0 -43
  109. package/resources/node-bacnet/lib/services/read-property-multiple.js +0 -50
  110. package/resources/node-bacnet/lib/services/read-property.js +0 -130
  111. package/resources/node-bacnet/lib/services/read-range.js +0 -201
  112. package/resources/node-bacnet/lib/services/register-foreign-device.js +0 -18
  113. package/resources/node-bacnet/lib/services/reinitialize-device.js +0 -37
  114. package/resources/node-bacnet/lib/services/subscribe-cov.js +0 -57
  115. package/resources/node-bacnet/lib/services/subscribe-property.js +0 -97
  116. package/resources/node-bacnet/lib/services/time-sync.js +0 -51
  117. package/resources/node-bacnet/lib/services/who-has.js +0 -54
  118. package/resources/node-bacnet/lib/services/who-is.js +0 -71
  119. package/resources/node-bacnet/lib/services/write-property-multiple.js +0 -117
  120. package/resources/node-bacnet/lib/services/write-property.js +0 -94
  121. package/resources/node-bacnet/lib/transport.js +0 -82
  122. 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
- });