@bitpoolos/edge-bacnet 1.4.7 → 1.5.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/CHANGELOG.md +106 -77
- package/bacnet_client.js +172 -97
- package/bacnet_device.js +18 -3
- package/bacnet_gateway.html +160 -40
- package/bacnet_gateway.js +4 -5
- package/bacnet_read.html +1032 -1008
- package/common.js +41 -1
- package/package.json +2 -2
- package/resources/node-bacstack-ts/dist/lib/client.js +161 -82
- package/resources/node-bacstack-ts/dist/lib/transport.js +57 -25
- package/resources/style.css +6 -6
package/bacnet_client.js
CHANGED
|
@@ -6,7 +6,15 @@ const bacnet = require("./resources/node-bacstack-ts/dist/index.js");
|
|
|
6
6
|
const baEnum = bacnet.enum;
|
|
7
7
|
const bacnetIdMax = baEnum.ASN1_MAX_PROPERTY_ID;
|
|
8
8
|
const { EventEmitter } = require("events");
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
getUnit,
|
|
11
|
+
roundDecimalPlaces,
|
|
12
|
+
parseBacnetError,
|
|
13
|
+
getBacnetErrorString,
|
|
14
|
+
Read_Config_Sync,
|
|
15
|
+
isNumber,
|
|
16
|
+
decodeBitArray,
|
|
17
|
+
} = require("./common");
|
|
10
18
|
const { ToadScheduler, SimpleIntervalJob, Task } = require("toad-scheduler");
|
|
11
19
|
const { BacnetDevice } = require("./bacnet_device");
|
|
12
20
|
const { Mutex } = require("async-mutex");
|
|
@@ -30,6 +38,7 @@ class BacnetClient extends EventEmitter {
|
|
|
30
38
|
that.buildJsonInProgress = false;
|
|
31
39
|
that.scanMatrix = [];
|
|
32
40
|
that.renderListCount = 0;
|
|
41
|
+
that.portRangeMatrix = config.portRangeMatrix;
|
|
33
42
|
|
|
34
43
|
try {
|
|
35
44
|
if (that.config.cacheFileEnabled) {
|
|
@@ -64,12 +73,12 @@ class BacnetClient extends EventEmitter {
|
|
|
64
73
|
};
|
|
65
74
|
|
|
66
75
|
try {
|
|
67
|
-
|
|
68
76
|
that.client = new bacnet.Client({
|
|
69
77
|
apduTimeout: config.apduTimeout,
|
|
70
78
|
interface: config.localIpAdrress,
|
|
71
79
|
port: config.port,
|
|
72
80
|
broadcastAddress: config.broadCastAddr,
|
|
81
|
+
portRangeMatrix: config.portRangeMatrix,
|
|
73
82
|
});
|
|
74
83
|
that.setMaxListeners(1);
|
|
75
84
|
|
|
@@ -185,15 +194,40 @@ class BacnetClient extends EventEmitter {
|
|
|
185
194
|
});
|
|
186
195
|
}
|
|
187
196
|
|
|
188
|
-
testFunction(address, type, instance, property) {
|
|
197
|
+
testFunction(address, port, type, instance, property) {
|
|
189
198
|
let that = this;
|
|
190
199
|
console.log("test function ");
|
|
200
|
+
|
|
201
|
+
let addressObject = {
|
|
202
|
+
address: address,
|
|
203
|
+
port: port,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const propertiesArray = [{ objectId: { type: type, instance: instance }, properties: [{ id: property }] }];
|
|
207
|
+
|
|
208
|
+
that.client.readPropertyMultiple(addressObject, propertiesArray, that.readPropertyMultipleOptions, (err, value) => {
|
|
209
|
+
console.log("1 - readPropertyMultiple: ");
|
|
210
|
+
|
|
211
|
+
console.log(value);
|
|
212
|
+
if (value) {
|
|
213
|
+
// If the result has value, resolve the promise
|
|
214
|
+
console.log(value.values[0]);
|
|
215
|
+
value.values[0].values.forEach(function (value) {
|
|
216
|
+
console.log("value: ", value.value);
|
|
217
|
+
});
|
|
218
|
+
} else {
|
|
219
|
+
console.log(err);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
191
223
|
that.client.readProperty(
|
|
192
|
-
|
|
224
|
+
addressObject,
|
|
193
225
|
{ type: type, instance: instance },
|
|
194
226
|
property,
|
|
195
227
|
that.readPropertyMultipleOptions,
|
|
196
228
|
(err, value) => {
|
|
229
|
+
console.log("2 - readProperty: ");
|
|
230
|
+
|
|
197
231
|
console.log(value);
|
|
198
232
|
if (value) {
|
|
199
233
|
// If the result has value, resolve the promise
|
|
@@ -254,9 +288,13 @@ class BacnetClient extends EventEmitter {
|
|
|
254
288
|
getProtocolSupported(device) {
|
|
255
289
|
//return protocols support for device
|
|
256
290
|
let that = this;
|
|
291
|
+
let addressObject = {
|
|
292
|
+
address: device.getAddress(),
|
|
293
|
+
port: device.getPort(),
|
|
294
|
+
};
|
|
257
295
|
return new Promise((resolve, reject) => {
|
|
258
296
|
that.client.readProperty(
|
|
259
|
-
|
|
297
|
+
addressObject,
|
|
260
298
|
{ type: baEnum.ObjectType.DEVICE, instance: device.getDeviceId() },
|
|
261
299
|
baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED,
|
|
262
300
|
that.readPropertyMultipleOptions,
|
|
@@ -482,10 +520,10 @@ class BacnetClient extends EventEmitter {
|
|
|
482
520
|
}
|
|
483
521
|
try {
|
|
484
522
|
await that.updateDeviceName(device);
|
|
523
|
+
|
|
485
524
|
if (device.getSegmentation() !== 3) {
|
|
486
525
|
try {
|
|
487
526
|
await that.getDevicePointList(device);
|
|
488
|
-
|
|
489
527
|
index++;
|
|
490
528
|
await query(index);
|
|
491
529
|
} catch (e) {
|
|
@@ -529,7 +567,7 @@ class BacnetClient extends EventEmitter {
|
|
|
529
567
|
let that = this;
|
|
530
568
|
return new Promise((resolve, reject) => {
|
|
531
569
|
that
|
|
532
|
-
._getDeviceName(device
|
|
570
|
+
._getDeviceName(device)
|
|
533
571
|
.then(function (deviceObject) {
|
|
534
572
|
if (typeof deviceObject.name == "string") {
|
|
535
573
|
device.setDeviceName(deviceObject.name + " " + device.getDeviceId());
|
|
@@ -538,7 +576,8 @@ class BacnetClient extends EventEmitter {
|
|
|
538
576
|
resolve();
|
|
539
577
|
})
|
|
540
578
|
.catch(function (e) {
|
|
541
|
-
|
|
579
|
+
that.logOut("updateDeviceName error: ", e);
|
|
580
|
+
resolve();
|
|
542
581
|
});
|
|
543
582
|
});
|
|
544
583
|
}
|
|
@@ -767,6 +806,7 @@ class BacnetClient extends EventEmitter {
|
|
|
767
806
|
|
|
768
807
|
if (isNumber(val)) {
|
|
769
808
|
pointRef.presentValue = roundDecimalPlaces(val, roundDecimal);
|
|
809
|
+
pointRef.error = "none";
|
|
770
810
|
if (pointRef.meta.objectId.type == 19 || pointRef.meta.objectId.type == 13 || pointRef.meta.objectId.type == 14) {
|
|
771
811
|
if (pointRef.stateTextArray && typeof pointRef.stateTextArray[0].value !== "object") {
|
|
772
812
|
if (val != 0) {
|
|
@@ -779,6 +819,9 @@ class BacnetClient extends EventEmitter {
|
|
|
779
819
|
} else {
|
|
780
820
|
if (typeof val !== "object") {
|
|
781
821
|
pointRef.presentValue = val;
|
|
822
|
+
pointRef.error = "none";
|
|
823
|
+
} else if (val.errorClass && val.errorClass) {
|
|
824
|
+
pointRef.error = getBacnetErrorString(val.errorClass, val.errorClass);
|
|
782
825
|
}
|
|
783
826
|
}
|
|
784
827
|
|
|
@@ -792,23 +835,7 @@ class BacnetClient extends EventEmitter {
|
|
|
792
835
|
});
|
|
793
836
|
} catch (err) {
|
|
794
837
|
that.logOut("Error processing batch:", err);
|
|
795
|
-
|
|
796
|
-
let deviceMetaInfo = {
|
|
797
|
-
address: device.getAddress(),
|
|
798
|
-
isMstp: device.getIsMstpDevice(),
|
|
799
|
-
deviceId: device.getDeviceId(),
|
|
800
|
-
vendorId: device.getVendorId(),
|
|
801
|
-
deviceName: deviceName,
|
|
802
|
-
};
|
|
803
|
-
|
|
804
|
-
requestArray.forEach((request) => {
|
|
805
|
-
let pointRef = request.pointRef;
|
|
806
|
-
pointRef.status = "offline";
|
|
807
|
-
pointRef.timestamp = Date.now();
|
|
808
|
-
pointRef.meta["device"] = deviceMetaInfo;
|
|
809
|
-
|
|
810
|
-
bacnetResults[deviceName][request.pointName] = pointRef;
|
|
811
|
-
});
|
|
838
|
+
await that.processIndividualPoints(device, requestArray, deviceName, bacnetResults, that, roundDecimal);
|
|
812
839
|
}
|
|
813
840
|
}
|
|
814
841
|
|
|
@@ -836,6 +863,7 @@ class BacnetClient extends EventEmitter {
|
|
|
836
863
|
pointRef.meta["device"] = deviceMetaInfo;
|
|
837
864
|
pointRef.timestamp = Date.now();
|
|
838
865
|
pointRef.status = "online";
|
|
866
|
+
pointRef.error = "none";
|
|
839
867
|
|
|
840
868
|
// Store the point data in results
|
|
841
869
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
@@ -845,6 +873,7 @@ class BacnetClient extends EventEmitter {
|
|
|
845
873
|
pointRef.meta["device"] = deviceMetaInfo;
|
|
846
874
|
pointRef.timestamp = Date.now();
|
|
847
875
|
pointRef.status = "offline";
|
|
876
|
+
pointRef.error = parseBacnetError(err);
|
|
848
877
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
849
878
|
}
|
|
850
879
|
}
|
|
@@ -854,7 +883,7 @@ class BacnetClient extends EventEmitter {
|
|
|
854
883
|
let that = this;
|
|
855
884
|
return new Promise((resolve, reject) => {
|
|
856
885
|
that
|
|
857
|
-
._readObjectWithRequestArray(device
|
|
886
|
+
._readObjectWithRequestArray(device, points, that.readPropertyMultipleOptions)
|
|
858
887
|
.then(function (results) {
|
|
859
888
|
resolve(results);
|
|
860
889
|
})
|
|
@@ -866,9 +895,13 @@ class BacnetClient extends EventEmitter {
|
|
|
866
895
|
|
|
867
896
|
updatePoint(device, point) {
|
|
868
897
|
let that = this;
|
|
898
|
+
let addressObject = {
|
|
899
|
+
address: device.getAddress(),
|
|
900
|
+
port: device.getPort(),
|
|
901
|
+
};
|
|
869
902
|
return new Promise((resolve, reject) => {
|
|
870
903
|
that.client.readProperty(
|
|
871
|
-
|
|
904
|
+
addressObject,
|
|
872
905
|
{ type: point.meta.objectId.type, instance: point.meta.objectId.instance },
|
|
873
906
|
baEnum.PropertyIdentifier.PRESENT_VALUE,
|
|
874
907
|
that.readPropertyMultipleOptions,
|
|
@@ -907,20 +940,21 @@ class BacnetClient extends EventEmitter {
|
|
|
907
940
|
}
|
|
908
941
|
}
|
|
909
942
|
|
|
910
|
-
_getDeviceName(
|
|
943
|
+
_getDeviceName(device) {
|
|
911
944
|
let that = this;
|
|
912
945
|
return new Promise((resolve, reject) => {
|
|
913
|
-
that._readDeviceName(
|
|
946
|
+
that._readDeviceName(device, (err, result) => {
|
|
914
947
|
if (result) {
|
|
915
948
|
try {
|
|
916
949
|
if (result.values[0].value) {
|
|
917
950
|
const deviceObject = {
|
|
918
951
|
name: result.values[0].value,
|
|
919
|
-
devicePointEntry: [{ value: { type: 8, instance:
|
|
952
|
+
devicePointEntry: [{ value: { type: 8, instance: device.getDeviceId() }, type: 12 }],
|
|
920
953
|
};
|
|
921
954
|
resolve(deviceObject);
|
|
922
955
|
} else {
|
|
923
|
-
that.logOut("Issue with deviceName payload, see object: ",
|
|
956
|
+
that.logOut("Issue with deviceName payload, see object: ", result);
|
|
957
|
+
resolve();
|
|
924
958
|
}
|
|
925
959
|
} catch (e) {
|
|
926
960
|
that.logOut("Unable to get device name: ", e);
|
|
@@ -1016,10 +1050,14 @@ class BacnetClient extends EventEmitter {
|
|
|
1016
1050
|
let that = this;
|
|
1017
1051
|
|
|
1018
1052
|
return new Promise(function (resolve, reject) {
|
|
1019
|
-
let address = device.getAddress();
|
|
1020
1053
|
let deviceId = device.getDeviceId();
|
|
1021
1054
|
let discoveredPointList = [];
|
|
1022
1055
|
|
|
1056
|
+
let addressObject = {
|
|
1057
|
+
address: device.getAddress(),
|
|
1058
|
+
port: device.getPort(),
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1023
1061
|
let index = 1;
|
|
1024
1062
|
|
|
1025
1063
|
send(index);
|
|
@@ -1032,7 +1070,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1032
1070
|
};
|
|
1033
1071
|
|
|
1034
1072
|
that.client.readProperty(
|
|
1035
|
-
|
|
1073
|
+
addressObject,
|
|
1036
1074
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1037
1075
|
baEnum.PropertyIdentifier.OBJECT_LIST,
|
|
1038
1076
|
readOptions,
|
|
@@ -1052,10 +1090,14 @@ class BacnetClient extends EventEmitter {
|
|
|
1052
1090
|
});
|
|
1053
1091
|
}
|
|
1054
1092
|
|
|
1055
|
-
_readObjectWithRequestArray(
|
|
1093
|
+
_readObjectWithRequestArray(device, requestArray, readOptions) {
|
|
1056
1094
|
let that = this;
|
|
1095
|
+
let addressObject = {
|
|
1096
|
+
address: device.getAddress(),
|
|
1097
|
+
port: device.getPort(),
|
|
1098
|
+
};
|
|
1057
1099
|
return new Promise((resolve, reject) => {
|
|
1058
|
-
|
|
1100
|
+
that.client.readPropertyMultiple(addressObject, requestArray, readOptions, (error, value) => {
|
|
1059
1101
|
resolve({
|
|
1060
1102
|
error: error,
|
|
1061
1103
|
value: value,
|
|
@@ -1064,10 +1106,17 @@ class BacnetClient extends EventEmitter {
|
|
|
1064
1106
|
});
|
|
1065
1107
|
}
|
|
1066
1108
|
|
|
1067
|
-
_readDeviceName(
|
|
1109
|
+
_readDeviceName(device, callback) {
|
|
1068
1110
|
let that = this;
|
|
1111
|
+
|
|
1112
|
+
let addressObject = {
|
|
1113
|
+
address: device.getAddress(),
|
|
1114
|
+
port: device.getPort(),
|
|
1115
|
+
};
|
|
1116
|
+
let deviceId = device.getDeviceId();
|
|
1117
|
+
|
|
1069
1118
|
that.client.readProperty(
|
|
1070
|
-
|
|
1119
|
+
addressObject,
|
|
1071
1120
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1072
1121
|
baEnum.PropertyIdentifier.OBJECT_NAME,
|
|
1073
1122
|
that.readPropertyMultipleOptions,
|
|
@@ -1075,12 +1124,16 @@ class BacnetClient extends EventEmitter {
|
|
|
1075
1124
|
);
|
|
1076
1125
|
}
|
|
1077
1126
|
|
|
1078
|
-
_readObjectList(
|
|
1127
|
+
_readObjectList(device, readOptions, callback) {
|
|
1079
1128
|
let that = this;
|
|
1080
|
-
|
|
1129
|
+
let addressObject = {
|
|
1130
|
+
address: device.getAddress(),
|
|
1131
|
+
port: device.getPort(),
|
|
1132
|
+
};
|
|
1133
|
+
let deviceId = device.getDeviceId();
|
|
1081
1134
|
try {
|
|
1082
1135
|
that.client.readProperty(
|
|
1083
|
-
|
|
1136
|
+
addressObject,
|
|
1084
1137
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1085
1138
|
baEnum.PropertyIdentifier.OBJECT_LIST,
|
|
1086
1139
|
readOptions,
|
|
@@ -1091,7 +1144,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1091
1144
|
}
|
|
1092
1145
|
}
|
|
1093
1146
|
|
|
1094
|
-
_readObject(
|
|
1147
|
+
_readObject(addressObject, type, instance, properties, readOptions) {
|
|
1095
1148
|
let that = this;
|
|
1096
1149
|
return new Promise((resolve, reject) => {
|
|
1097
1150
|
const requestArray = [
|
|
@@ -1100,7 +1153,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1100
1153
|
properties: properties,
|
|
1101
1154
|
},
|
|
1102
1155
|
];
|
|
1103
|
-
|
|
1156
|
+
that.client.readPropertyMultiple(addressObject, requestArray, readOptions, (error, value) => {
|
|
1104
1157
|
resolve({
|
|
1105
1158
|
error: error,
|
|
1106
1159
|
value: value,
|
|
@@ -1109,13 +1162,23 @@ class BacnetClient extends EventEmitter {
|
|
|
1109
1162
|
});
|
|
1110
1163
|
}
|
|
1111
1164
|
|
|
1112
|
-
_readObjectFull(device,
|
|
1165
|
+
_readObjectFull(device, type, instance) {
|
|
1113
1166
|
const that = this;
|
|
1114
1167
|
const readOptions = {
|
|
1115
1168
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1116
1169
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1117
1170
|
};
|
|
1118
1171
|
|
|
1172
|
+
const readIndividualPropsOptions = {
|
|
1173
|
+
maxSegments: 0,
|
|
1174
|
+
maxApdu: device.getMaxApdu(),
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
let addressObject = {
|
|
1178
|
+
address: device.getAddress(),
|
|
1179
|
+
port: device.getPort(),
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1119
1182
|
// Define all properties to be read
|
|
1120
1183
|
const allProperties = [
|
|
1121
1184
|
{ id: baEnum.PropertyIdentifier.PRESENT_VALUE },
|
|
@@ -1135,7 +1198,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1135
1198
|
return new Promise((resolve, reject) => {
|
|
1136
1199
|
// Try to read all properties at once
|
|
1137
1200
|
that
|
|
1138
|
-
._readObject(
|
|
1201
|
+
._readObject(addressObject, type, instance, [{ id: baEnum.PropertyIdentifier.ALL }], readOptions)
|
|
1139
1202
|
.then((result) => {
|
|
1140
1203
|
if (result.value) {
|
|
1141
1204
|
// If the result has value, resolve the promise
|
|
@@ -1156,10 +1219,10 @@ class BacnetClient extends EventEmitter {
|
|
|
1156
1219
|
(property, index) =>
|
|
1157
1220
|
new Promise((propertyResolve) => {
|
|
1158
1221
|
that.client.readProperty(
|
|
1159
|
-
|
|
1222
|
+
addressObject,
|
|
1160
1223
|
{ type: type, instance: instance },
|
|
1161
1224
|
property.id,
|
|
1162
|
-
|
|
1225
|
+
readIndividualPropsOptions,
|
|
1163
1226
|
(err, value) => {
|
|
1164
1227
|
if (err) {
|
|
1165
1228
|
propertyResolve(null);
|
|
@@ -1200,20 +1263,30 @@ class BacnetClient extends EventEmitter {
|
|
|
1200
1263
|
});
|
|
1201
1264
|
}
|
|
1202
1265
|
|
|
1203
|
-
_readObjectLite(device,
|
|
1266
|
+
_readObjectLite(device, type, instance) {
|
|
1204
1267
|
const that = this;
|
|
1205
1268
|
const readOptions = {
|
|
1206
1269
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1207
1270
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1208
1271
|
};
|
|
1209
1272
|
|
|
1273
|
+
const readIndividualPropsOptions = {
|
|
1274
|
+
maxSegments: 0,
|
|
1275
|
+
maxApdu: device.getMaxApdu(),
|
|
1276
|
+
};
|
|
1277
|
+
|
|
1278
|
+
let addressObject = {
|
|
1279
|
+
address: device.getAddress(),
|
|
1280
|
+
port: device.getPort(),
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1210
1283
|
// Define all properties to be read
|
|
1211
1284
|
const allProperties = [{ id: baEnum.PropertyIdentifier.PRESENT_VALUE }, { id: baEnum.PropertyIdentifier.OBJECT_NAME }];
|
|
1212
1285
|
|
|
1213
1286
|
return new Promise((resolve, reject) => {
|
|
1214
1287
|
// Try to read all properties at once
|
|
1215
1288
|
that
|
|
1216
|
-
._readObject(
|
|
1289
|
+
._readObject(addressObject, type, instance, allProperties, readOptions)
|
|
1217
1290
|
.then((result) => {
|
|
1218
1291
|
if (result.value) {
|
|
1219
1292
|
// If the result has value, resolve the promise
|
|
@@ -1234,10 +1307,10 @@ class BacnetClient extends EventEmitter {
|
|
|
1234
1307
|
(property, index) =>
|
|
1235
1308
|
new Promise((propertyResolve) => {
|
|
1236
1309
|
that.client.readProperty(
|
|
1237
|
-
|
|
1310
|
+
addressObject,
|
|
1238
1311
|
{ type: type, instance: instance },
|
|
1239
1312
|
property.id,
|
|
1240
|
-
|
|
1313
|
+
readIndividualPropsOptions,
|
|
1241
1314
|
(err, value) => {
|
|
1242
1315
|
if (err) {
|
|
1243
1316
|
propertyResolve(null);
|
|
@@ -1278,53 +1351,47 @@ class BacnetClient extends EventEmitter {
|
|
|
1278
1351
|
});
|
|
1279
1352
|
}
|
|
1280
1353
|
|
|
1281
|
-
_readObjectPropList(deviceAddress, type, instance) {
|
|
1282
|
-
return this._readObject(deviceAddress, type, instance, [{ id: baEnum.PropertyIdentifier.PROPERTY_LIST }]);
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
_readObjectId(deviceAddress, type, instance) {
|
|
1286
|
-
return this._readObject(deviceAddress, type, instance, [{ id: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER }]);
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
_readObjectPresentValue(deviceAddress, type, instance) {
|
|
1290
|
-
return this._readObject(deviceAddress, type, instance, [
|
|
1291
|
-
{ id: baEnum.PropertyIdentifier.PRESENT_VALUE },
|
|
1292
|
-
{ id: baEnum.PropertyIdentifier.OBJECT_NAME },
|
|
1293
|
-
]);
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
1354
|
doWrite(value, options) {
|
|
1297
1355
|
let that = this;
|
|
1298
1356
|
let valuesArray = [];
|
|
1299
1357
|
options.pointsToWrite.forEach(function (point) {
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1358
|
+
try {
|
|
1359
|
+
let device = that.deviceList.find((ele) => ele.getDeviceId() === point.deviceId);
|
|
1360
|
+
let addressObject = {
|
|
1361
|
+
address: device.getAddress(),
|
|
1362
|
+
port: device.getPort(),
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
let writeObject = {
|
|
1366
|
+
address: addressObject,
|
|
1367
|
+
objectId: {
|
|
1368
|
+
type: point.meta.objectId.type,
|
|
1369
|
+
instance: point.meta.objectId.instance,
|
|
1311
1370
|
},
|
|
1312
|
-
|
|
1313
|
-
{
|
|
1314
|
-
|
|
1315
|
-
|
|
1371
|
+
values: {
|
|
1372
|
+
property: {
|
|
1373
|
+
id: 85,
|
|
1374
|
+
index: point.meta.arrayIndex,
|
|
1316
1375
|
},
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1376
|
+
value: [
|
|
1377
|
+
{
|
|
1378
|
+
type: options.appTag,
|
|
1379
|
+
value: value,
|
|
1380
|
+
},
|
|
1381
|
+
],
|
|
1382
|
+
},
|
|
1383
|
+
options: {
|
|
1384
|
+
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1385
|
+
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1386
|
+
arrayIndex: point.meta.arrayIndex,
|
|
1387
|
+
priority: options.priority,
|
|
1388
|
+
},
|
|
1389
|
+
};
|
|
1326
1390
|
|
|
1327
|
-
|
|
1391
|
+
valuesArray.push(writeObject);
|
|
1392
|
+
} catch (e) {
|
|
1393
|
+
that.logOut("doWrite error: ", e);
|
|
1394
|
+
}
|
|
1328
1395
|
});
|
|
1329
1396
|
|
|
1330
1397
|
return that._writePropertyMultiple(valuesArray);
|
|
@@ -1348,7 +1415,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1348
1415
|
);
|
|
1349
1416
|
});
|
|
1350
1417
|
} catch (error) {
|
|
1351
|
-
that.logOut(error);
|
|
1418
|
+
that.logOut("_writePropertyMultiple error: ", error);
|
|
1352
1419
|
}
|
|
1353
1420
|
}
|
|
1354
1421
|
|
|
@@ -1370,7 +1437,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1370
1437
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1371
1438
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1372
1439
|
};
|
|
1373
|
-
this._readObjectList(device
|
|
1440
|
+
this._readObjectList(device, readOptions, (err, result) => {
|
|
1374
1441
|
if (!err) {
|
|
1375
1442
|
try {
|
|
1376
1443
|
resolve(result.values);
|
|
@@ -1437,6 +1504,17 @@ class BacnetClient extends EventEmitter {
|
|
|
1437
1504
|
});
|
|
1438
1505
|
}
|
|
1439
1506
|
|
|
1507
|
+
updatePointsList(json) {
|
|
1508
|
+
let that = this;
|
|
1509
|
+
json.deviceList.forEach(function (updatedDevice) {
|
|
1510
|
+
let foundIndex = that.deviceList.findIndex((ele) => ele.getDeviceId() == updatedDevice.deviceId);
|
|
1511
|
+
if (foundIndex == -1) {
|
|
1512
|
+
} else if (foundIndex !== -1) {
|
|
1513
|
+
that.deviceList[foundIndex].setPointsList(updatedDevice.pointsList);
|
|
1514
|
+
}
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1440
1518
|
updateDeviceList(json) {
|
|
1441
1519
|
let that = this;
|
|
1442
1520
|
return new Promise(async function (resolve, reject) {
|
|
@@ -1619,10 +1697,8 @@ class BacnetClient extends EventEmitter {
|
|
|
1619
1697
|
that.buildJsonInProgress = false;
|
|
1620
1698
|
}
|
|
1621
1699
|
|
|
1622
|
-
|
|
1623
1700
|
async buildJsonObject(device) {
|
|
1624
1701
|
try {
|
|
1625
|
-
const address = device.address;
|
|
1626
1702
|
const pointList = device.getPointsList();
|
|
1627
1703
|
const requestMutex = new Mutex();
|
|
1628
1704
|
const promiseArray = [];
|
|
@@ -1633,13 +1709,12 @@ class BacnetClient extends EventEmitter {
|
|
|
1633
1709
|
|
|
1634
1710
|
for (const point of pointList) {
|
|
1635
1711
|
await requestMutex.acquire();
|
|
1636
|
-
|
|
1637
1712
|
let result;
|
|
1638
1713
|
if (device.getIsInitialQuery()) {
|
|
1639
|
-
result = await this._readObjectLite(device,
|
|
1714
|
+
result = await this._readObjectLite(device, point.value.type, point.value.instance);
|
|
1640
1715
|
device.setIsInitialQuery(false);
|
|
1641
1716
|
} else {
|
|
1642
|
-
result = await this._readObjectFull(device,
|
|
1717
|
+
result = await this._readObjectFull(device, point.value.type, point.value.instance);
|
|
1643
1718
|
}
|
|
1644
1719
|
|
|
1645
1720
|
if (!result.error) {
|
package/bacnet_device.js
CHANGED
|
@@ -36,6 +36,7 @@ class BacnetDevice {
|
|
|
36
36
|
that.isProtocolServicesSet = config.isProtocolServicesSet;
|
|
37
37
|
that.isInitialQuery = config.isInitialQuery;
|
|
38
38
|
that.isDumbMstpRouter = config.isDumbMstpRouter;
|
|
39
|
+
that.port = config.port;
|
|
39
40
|
|
|
40
41
|
} else if (fromImport == false) {
|
|
41
42
|
if (config.net && config.adr) {
|
|
@@ -66,9 +67,18 @@ class BacnetDevice {
|
|
|
66
67
|
that.isProtocolServicesSet = false;
|
|
67
68
|
that.isInitialQuery = true;
|
|
68
69
|
that.isDumbMstpRouter = false;
|
|
70
|
+
that.port = config.port;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
setPort(port) {
|
|
75
|
+
this.port = port;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getPort() {
|
|
79
|
+
return this.port;
|
|
80
|
+
}
|
|
81
|
+
|
|
72
82
|
setIsDumbMstpRouter(isDumbMstp) {
|
|
73
83
|
this.isDumbMstpRouter = isDumbMstp;
|
|
74
84
|
}
|
|
@@ -190,6 +200,10 @@ class BacnetDevice {
|
|
|
190
200
|
if (Number.isInteger(config.maxApdu)) this.maxApdu = config.maxApdu;
|
|
191
201
|
if (Number.isInteger(config.segmentation)) this.segmentation = config.segmentation;
|
|
192
202
|
if (Number.isInteger(config.vendorId)) this.vendorId = config.vendorId;
|
|
203
|
+
if (config.pointsList && config.pointsList.length > 0) {
|
|
204
|
+
this.setPointsList(config.pointsList);
|
|
205
|
+
}
|
|
206
|
+
if (config.port) this.port = config.port;
|
|
193
207
|
}
|
|
194
208
|
|
|
195
209
|
getPointListRetryCount() {
|
|
@@ -244,9 +258,10 @@ class BacnetDevice {
|
|
|
244
258
|
point.value.type == 3 || //BI
|
|
245
259
|
point.value.type == 4 || //BV
|
|
246
260
|
point.value.type == 5 || //BO
|
|
247
|
-
point.value.type == 13 ||
|
|
248
|
-
point.value.type == 14 ||
|
|
249
|
-
point.value.type == 19
|
|
261
|
+
point.value.type == 13 || //MSI
|
|
262
|
+
point.value.type == 14 || //MSO
|
|
263
|
+
point.value.type == 19 || //MSV
|
|
264
|
+
point.value.type == 40 //CS
|
|
250
265
|
);
|
|
251
266
|
}
|
|
252
267
|
|