@bitpoolos/edge-bacnet 1.4.6 → 1.5.0
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 +22 -0
- package/bacnet_client.js +146 -95
- package/bacnet_device.js +18 -3
- package/bacnet_gateway.html +141 -7
- package/bacnet_gateway.js +4 -5
- package/bacnet_read.html +34 -19
- package/common.js +41 -1
- package/package.json +1 -1
- 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 +1 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.0] - 31-10-2024
|
|
4
|
+
### Summary
|
|
5
|
+
|
|
6
|
+
Major feature release - Port range binding
|
|
7
|
+
|
|
8
|
+
Large amount of bug fixes
|
|
9
|
+
|
|
10
|
+
Added error string to Full Object payload. Contains a BACnet string where an error is found for point, otherwise contains "none".
|
|
11
|
+
|
|
12
|
+
Proceed with caution as a correct port range has to be established in data model in order to continue uptime on existing sites. Doing a device discovery will update device model with port number.
|
|
13
|
+
|
|
14
|
+
Best method to update this version on existing installs:
|
|
15
|
+
|
|
16
|
+
- Install v1.5.0
|
|
17
|
+
- Restart node-red / docker container
|
|
18
|
+
- Add new port range entry to port range matrix in gateway node - Start: 47808 to End: 47808. Or any range that meets your requirements
|
|
19
|
+
- Deploy changes
|
|
20
|
+
- Restart node-red / docker container again.
|
|
21
|
+
- Inject manual discovery to gateway node a couple times
|
|
22
|
+
|
|
23
|
+
It is recommended you back up: your node-red flows and gateway Discovery tab device list, incase something goes wrong.
|
|
24
|
+
|
|
3
25
|
## [1.4.6] - 17-09-2024
|
|
4
26
|
### Summary
|
|
5
27
|
|
package/bacnet_client.js
CHANGED
|
@@ -6,7 +6,7 @@ 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 { getUnit, roundDecimalPlaces,
|
|
9
|
+
const { getUnit, roundDecimalPlaces, parseBacnetError, getBacnetErrorString, Read_Config_Sync, isNumber, decodeBitArray } = require("./common");
|
|
10
10
|
const { ToadScheduler, SimpleIntervalJob, Task } = require("toad-scheduler");
|
|
11
11
|
const { BacnetDevice } = require("./bacnet_device");
|
|
12
12
|
const { Mutex } = require("async-mutex");
|
|
@@ -30,6 +30,7 @@ class BacnetClient extends EventEmitter {
|
|
|
30
30
|
that.buildJsonInProgress = false;
|
|
31
31
|
that.scanMatrix = [];
|
|
32
32
|
that.renderListCount = 0;
|
|
33
|
+
that.portRangeMatrix = config.portRangeMatrix;
|
|
33
34
|
|
|
34
35
|
try {
|
|
35
36
|
if (that.config.cacheFileEnabled) {
|
|
@@ -70,6 +71,7 @@ class BacnetClient extends EventEmitter {
|
|
|
70
71
|
interface: config.localIpAdrress,
|
|
71
72
|
port: config.port,
|
|
72
73
|
broadcastAddress: config.broadCastAddr,
|
|
74
|
+
portRangeMatrix: config.portRangeMatrix
|
|
73
75
|
});
|
|
74
76
|
that.setMaxListeners(1);
|
|
75
77
|
|
|
@@ -185,11 +187,17 @@ class BacnetClient extends EventEmitter {
|
|
|
185
187
|
});
|
|
186
188
|
}
|
|
187
189
|
|
|
188
|
-
testFunction(address, type, instance, property) {
|
|
190
|
+
testFunction(address, port, type, instance, property) {
|
|
189
191
|
let that = this;
|
|
190
192
|
console.log("test function ");
|
|
193
|
+
|
|
194
|
+
let addressObject = {
|
|
195
|
+
address: address,
|
|
196
|
+
port: port
|
|
197
|
+
};
|
|
198
|
+
|
|
191
199
|
that.client.readProperty(
|
|
192
|
-
|
|
200
|
+
addressObject,
|
|
193
201
|
{ type: type, instance: instance },
|
|
194
202
|
property,
|
|
195
203
|
that.readPropertyMultipleOptions,
|
|
@@ -254,9 +262,13 @@ class BacnetClient extends EventEmitter {
|
|
|
254
262
|
getProtocolSupported(device) {
|
|
255
263
|
//return protocols support for device
|
|
256
264
|
let that = this;
|
|
265
|
+
let addressObject = {
|
|
266
|
+
address: device.getAddress(),
|
|
267
|
+
port: device.getPort()
|
|
268
|
+
};
|
|
257
269
|
return new Promise((resolve, reject) => {
|
|
258
270
|
that.client.readProperty(
|
|
259
|
-
|
|
271
|
+
addressObject,
|
|
260
272
|
{ type: baEnum.ObjectType.DEVICE, instance: device.getDeviceId() },
|
|
261
273
|
baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED,
|
|
262
274
|
that.readPropertyMultipleOptions,
|
|
@@ -482,10 +494,10 @@ class BacnetClient extends EventEmitter {
|
|
|
482
494
|
}
|
|
483
495
|
try {
|
|
484
496
|
await that.updateDeviceName(device);
|
|
497
|
+
|
|
485
498
|
if (device.getSegmentation() !== 3) {
|
|
486
499
|
try {
|
|
487
500
|
await that.getDevicePointList(device);
|
|
488
|
-
|
|
489
501
|
index++;
|
|
490
502
|
await query(index);
|
|
491
503
|
} catch (e) {
|
|
@@ -529,7 +541,7 @@ class BacnetClient extends EventEmitter {
|
|
|
529
541
|
let that = this;
|
|
530
542
|
return new Promise((resolve, reject) => {
|
|
531
543
|
that
|
|
532
|
-
._getDeviceName(device
|
|
544
|
+
._getDeviceName(device)
|
|
533
545
|
.then(function (deviceObject) {
|
|
534
546
|
if (typeof deviceObject.name == "string") {
|
|
535
547
|
device.setDeviceName(deviceObject.name + " " + device.getDeviceId());
|
|
@@ -538,7 +550,8 @@ class BacnetClient extends EventEmitter {
|
|
|
538
550
|
resolve();
|
|
539
551
|
})
|
|
540
552
|
.catch(function (e) {
|
|
541
|
-
|
|
553
|
+
that.logOut("updateDeviceName error: ", e);
|
|
554
|
+
resolve();
|
|
542
555
|
});
|
|
543
556
|
});
|
|
544
557
|
}
|
|
@@ -767,6 +780,7 @@ class BacnetClient extends EventEmitter {
|
|
|
767
780
|
|
|
768
781
|
if (isNumber(val)) {
|
|
769
782
|
pointRef.presentValue = roundDecimalPlaces(val, roundDecimal);
|
|
783
|
+
pointRef.error = "none";
|
|
770
784
|
if (pointRef.meta.objectId.type == 19 || pointRef.meta.objectId.type == 13 || pointRef.meta.objectId.type == 14) {
|
|
771
785
|
if (pointRef.stateTextArray && typeof pointRef.stateTextArray[0].value !== "object") {
|
|
772
786
|
if (val != 0) {
|
|
@@ -779,6 +793,9 @@ class BacnetClient extends EventEmitter {
|
|
|
779
793
|
} else {
|
|
780
794
|
if (typeof val !== "object") {
|
|
781
795
|
pointRef.presentValue = val;
|
|
796
|
+
pointRef.error = "none";
|
|
797
|
+
} else if (val.errorClass && val.errorClass) {
|
|
798
|
+
pointRef.error = getBacnetErrorString(val.errorClass, val.errorClass);
|
|
782
799
|
}
|
|
783
800
|
}
|
|
784
801
|
|
|
@@ -792,23 +809,7 @@ class BacnetClient extends EventEmitter {
|
|
|
792
809
|
});
|
|
793
810
|
} catch (err) {
|
|
794
811
|
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
|
-
});
|
|
812
|
+
await that.processIndividualPoints(device, requestArray, deviceName, bacnetResults, that, roundDecimal);
|
|
812
813
|
}
|
|
813
814
|
}
|
|
814
815
|
|
|
@@ -836,6 +837,7 @@ class BacnetClient extends EventEmitter {
|
|
|
836
837
|
pointRef.meta["device"] = deviceMetaInfo;
|
|
837
838
|
pointRef.timestamp = Date.now();
|
|
838
839
|
pointRef.status = "online";
|
|
840
|
+
pointRef.error = "none";
|
|
839
841
|
|
|
840
842
|
// Store the point data in results
|
|
841
843
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
@@ -845,6 +847,7 @@ class BacnetClient extends EventEmitter {
|
|
|
845
847
|
pointRef.meta["device"] = deviceMetaInfo;
|
|
846
848
|
pointRef.timestamp = Date.now();
|
|
847
849
|
pointRef.status = "offline";
|
|
850
|
+
pointRef.error = parseBacnetError(err);
|
|
848
851
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
849
852
|
}
|
|
850
853
|
}
|
|
@@ -854,7 +857,7 @@ class BacnetClient extends EventEmitter {
|
|
|
854
857
|
let that = this;
|
|
855
858
|
return new Promise((resolve, reject) => {
|
|
856
859
|
that
|
|
857
|
-
._readObjectWithRequestArray(device
|
|
860
|
+
._readObjectWithRequestArray(device, points, that.readPropertyMultipleOptions)
|
|
858
861
|
.then(function (results) {
|
|
859
862
|
resolve(results);
|
|
860
863
|
})
|
|
@@ -866,9 +869,13 @@ class BacnetClient extends EventEmitter {
|
|
|
866
869
|
|
|
867
870
|
updatePoint(device, point) {
|
|
868
871
|
let that = this;
|
|
872
|
+
let addressObject = {
|
|
873
|
+
address: device.getAddress(),
|
|
874
|
+
port: device.getPort()
|
|
875
|
+
};
|
|
869
876
|
return new Promise((resolve, reject) => {
|
|
870
877
|
that.client.readProperty(
|
|
871
|
-
|
|
878
|
+
addressObject,
|
|
872
879
|
{ type: point.meta.objectId.type, instance: point.meta.objectId.instance },
|
|
873
880
|
baEnum.PropertyIdentifier.PRESENT_VALUE,
|
|
874
881
|
that.readPropertyMultipleOptions,
|
|
@@ -907,20 +914,21 @@ class BacnetClient extends EventEmitter {
|
|
|
907
914
|
}
|
|
908
915
|
}
|
|
909
916
|
|
|
910
|
-
_getDeviceName(
|
|
917
|
+
_getDeviceName(device) {
|
|
911
918
|
let that = this;
|
|
912
919
|
return new Promise((resolve, reject) => {
|
|
913
|
-
that._readDeviceName(
|
|
920
|
+
that._readDeviceName(device, (err, result) => {
|
|
914
921
|
if (result) {
|
|
915
922
|
try {
|
|
916
923
|
if (result.values[0].value) {
|
|
917
924
|
const deviceObject = {
|
|
918
925
|
name: result.values[0].value,
|
|
919
|
-
devicePointEntry: [{ value: { type: 8, instance:
|
|
926
|
+
devicePointEntry: [{ value: { type: 8, instance: device.getDeviceId() }, type: 12 }],
|
|
920
927
|
};
|
|
921
928
|
resolve(deviceObject);
|
|
922
929
|
} else {
|
|
923
|
-
that.logOut("Issue with deviceName payload, see object: ",
|
|
930
|
+
that.logOut("Issue with deviceName payload, see object: ", result);
|
|
931
|
+
resolve();
|
|
924
932
|
}
|
|
925
933
|
} catch (e) {
|
|
926
934
|
that.logOut("Unable to get device name: ", e);
|
|
@@ -1016,10 +1024,14 @@ class BacnetClient extends EventEmitter {
|
|
|
1016
1024
|
let that = this;
|
|
1017
1025
|
|
|
1018
1026
|
return new Promise(function (resolve, reject) {
|
|
1019
|
-
let address = device.getAddress();
|
|
1020
1027
|
let deviceId = device.getDeviceId();
|
|
1021
1028
|
let discoveredPointList = [];
|
|
1022
1029
|
|
|
1030
|
+
let addressObject = {
|
|
1031
|
+
address: device.getAddress(),
|
|
1032
|
+
port: device.getPort()
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1023
1035
|
let index = 1;
|
|
1024
1036
|
|
|
1025
1037
|
send(index);
|
|
@@ -1032,7 +1044,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1032
1044
|
};
|
|
1033
1045
|
|
|
1034
1046
|
that.client.readProperty(
|
|
1035
|
-
|
|
1047
|
+
addressObject,
|
|
1036
1048
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1037
1049
|
baEnum.PropertyIdentifier.OBJECT_LIST,
|
|
1038
1050
|
readOptions,
|
|
@@ -1052,10 +1064,14 @@ class BacnetClient extends EventEmitter {
|
|
|
1052
1064
|
});
|
|
1053
1065
|
}
|
|
1054
1066
|
|
|
1055
|
-
_readObjectWithRequestArray(
|
|
1067
|
+
_readObjectWithRequestArray(device, requestArray, readOptions) {
|
|
1056
1068
|
let that = this;
|
|
1069
|
+
let addressObject = {
|
|
1070
|
+
address: device.getAddress(),
|
|
1071
|
+
port: device.getPort()
|
|
1072
|
+
};
|
|
1057
1073
|
return new Promise((resolve, reject) => {
|
|
1058
|
-
|
|
1074
|
+
that.client.readPropertyMultiple(addressObject, requestArray, readOptions, (error, value) => {
|
|
1059
1075
|
resolve({
|
|
1060
1076
|
error: error,
|
|
1061
1077
|
value: value,
|
|
@@ -1064,10 +1080,17 @@ class BacnetClient extends EventEmitter {
|
|
|
1064
1080
|
});
|
|
1065
1081
|
}
|
|
1066
1082
|
|
|
1067
|
-
_readDeviceName(
|
|
1083
|
+
_readDeviceName(device, callback) {
|
|
1068
1084
|
let that = this;
|
|
1085
|
+
|
|
1086
|
+
let addressObject = {
|
|
1087
|
+
address: device.getAddress(),
|
|
1088
|
+
port: device.getPort()
|
|
1089
|
+
};
|
|
1090
|
+
let deviceId = device.getDeviceId();
|
|
1091
|
+
|
|
1069
1092
|
that.client.readProperty(
|
|
1070
|
-
|
|
1093
|
+
addressObject,
|
|
1071
1094
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1072
1095
|
baEnum.PropertyIdentifier.OBJECT_NAME,
|
|
1073
1096
|
that.readPropertyMultipleOptions,
|
|
@@ -1075,12 +1098,16 @@ class BacnetClient extends EventEmitter {
|
|
|
1075
1098
|
);
|
|
1076
1099
|
}
|
|
1077
1100
|
|
|
1078
|
-
_readObjectList(
|
|
1101
|
+
_readObjectList(device, readOptions, callback) {
|
|
1079
1102
|
let that = this;
|
|
1080
|
-
|
|
1103
|
+
let addressObject = {
|
|
1104
|
+
address: device.getAddress(),
|
|
1105
|
+
port: device.getPort()
|
|
1106
|
+
};
|
|
1107
|
+
let deviceId = device.getDeviceId();
|
|
1081
1108
|
try {
|
|
1082
1109
|
that.client.readProperty(
|
|
1083
|
-
|
|
1110
|
+
addressObject,
|
|
1084
1111
|
{ type: baEnum.ObjectType.DEVICE, instance: deviceId },
|
|
1085
1112
|
baEnum.PropertyIdentifier.OBJECT_LIST,
|
|
1086
1113
|
readOptions,
|
|
@@ -1091,7 +1118,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1091
1118
|
}
|
|
1092
1119
|
}
|
|
1093
1120
|
|
|
1094
|
-
_readObject(
|
|
1121
|
+
_readObject(addressObject, type, instance, properties, readOptions) {
|
|
1095
1122
|
let that = this;
|
|
1096
1123
|
return new Promise((resolve, reject) => {
|
|
1097
1124
|
const requestArray = [
|
|
@@ -1100,7 +1127,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1100
1127
|
properties: properties,
|
|
1101
1128
|
},
|
|
1102
1129
|
];
|
|
1103
|
-
|
|
1130
|
+
that.client.readPropertyMultiple(addressObject, requestArray, readOptions, (error, value) => {
|
|
1104
1131
|
resolve({
|
|
1105
1132
|
error: error,
|
|
1106
1133
|
value: value,
|
|
@@ -1109,13 +1136,23 @@ class BacnetClient extends EventEmitter {
|
|
|
1109
1136
|
});
|
|
1110
1137
|
}
|
|
1111
1138
|
|
|
1112
|
-
_readObjectFull(device,
|
|
1139
|
+
_readObjectFull(device, type, instance) {
|
|
1113
1140
|
const that = this;
|
|
1114
1141
|
const readOptions = {
|
|
1115
1142
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1116
1143
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1117
1144
|
};
|
|
1118
1145
|
|
|
1146
|
+
const readIndividualPropsOptions = {
|
|
1147
|
+
maxSegments: 0,
|
|
1148
|
+
maxApdu: device.getMaxApdu(),
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
let addressObject = {
|
|
1152
|
+
address: device.getAddress(),
|
|
1153
|
+
port: device.getPort()
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1119
1156
|
// Define all properties to be read
|
|
1120
1157
|
const allProperties = [
|
|
1121
1158
|
{ id: baEnum.PropertyIdentifier.PRESENT_VALUE },
|
|
@@ -1135,7 +1172,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1135
1172
|
return new Promise((resolve, reject) => {
|
|
1136
1173
|
// Try to read all properties at once
|
|
1137
1174
|
that
|
|
1138
|
-
._readObject(
|
|
1175
|
+
._readObject(addressObject, type, instance, [{ id: baEnum.PropertyIdentifier.ALL }], readOptions)
|
|
1139
1176
|
.then((result) => {
|
|
1140
1177
|
if (result.value) {
|
|
1141
1178
|
// If the result has value, resolve the promise
|
|
@@ -1156,10 +1193,10 @@ class BacnetClient extends EventEmitter {
|
|
|
1156
1193
|
(property, index) =>
|
|
1157
1194
|
new Promise((propertyResolve) => {
|
|
1158
1195
|
that.client.readProperty(
|
|
1159
|
-
|
|
1196
|
+
addressObject,
|
|
1160
1197
|
{ type: type, instance: instance },
|
|
1161
1198
|
property.id,
|
|
1162
|
-
|
|
1199
|
+
readIndividualPropsOptions,
|
|
1163
1200
|
(err, value) => {
|
|
1164
1201
|
if (err) {
|
|
1165
1202
|
propertyResolve(null);
|
|
@@ -1200,20 +1237,30 @@ class BacnetClient extends EventEmitter {
|
|
|
1200
1237
|
});
|
|
1201
1238
|
}
|
|
1202
1239
|
|
|
1203
|
-
_readObjectLite(device,
|
|
1240
|
+
_readObjectLite(device, type, instance) {
|
|
1204
1241
|
const that = this;
|
|
1205
1242
|
const readOptions = {
|
|
1206
1243
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1207
1244
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1208
1245
|
};
|
|
1209
1246
|
|
|
1247
|
+
const readIndividualPropsOptions = {
|
|
1248
|
+
maxSegments: 0,
|
|
1249
|
+
maxApdu: device.getMaxApdu(),
|
|
1250
|
+
};
|
|
1251
|
+
|
|
1252
|
+
let addressObject = {
|
|
1253
|
+
address: device.getAddress(),
|
|
1254
|
+
port: device.getPort()
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1210
1257
|
// Define all properties to be read
|
|
1211
1258
|
const allProperties = [{ id: baEnum.PropertyIdentifier.PRESENT_VALUE }, { id: baEnum.PropertyIdentifier.OBJECT_NAME }];
|
|
1212
1259
|
|
|
1213
1260
|
return new Promise((resolve, reject) => {
|
|
1214
1261
|
// Try to read all properties at once
|
|
1215
1262
|
that
|
|
1216
|
-
._readObject(
|
|
1263
|
+
._readObject(addressObject, type, instance, allProperties, readOptions)
|
|
1217
1264
|
.then((result) => {
|
|
1218
1265
|
if (result.value) {
|
|
1219
1266
|
// If the result has value, resolve the promise
|
|
@@ -1234,10 +1281,10 @@ class BacnetClient extends EventEmitter {
|
|
|
1234
1281
|
(property, index) =>
|
|
1235
1282
|
new Promise((propertyResolve) => {
|
|
1236
1283
|
that.client.readProperty(
|
|
1237
|
-
|
|
1284
|
+
addressObject,
|
|
1238
1285
|
{ type: type, instance: instance },
|
|
1239
1286
|
property.id,
|
|
1240
|
-
|
|
1287
|
+
readIndividualPropsOptions,
|
|
1241
1288
|
(err, value) => {
|
|
1242
1289
|
if (err) {
|
|
1243
1290
|
propertyResolve(null);
|
|
@@ -1278,53 +1325,47 @@ class BacnetClient extends EventEmitter {
|
|
|
1278
1325
|
});
|
|
1279
1326
|
}
|
|
1280
1327
|
|
|
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
1328
|
doWrite(value, options) {
|
|
1297
1329
|
let that = this;
|
|
1298
1330
|
let valuesArray = [];
|
|
1299
1331
|
options.pointsToWrite.forEach(function (point) {
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1332
|
+
try {
|
|
1333
|
+
let device = that.deviceList.find((ele) => ele.getDeviceId() === point.deviceId);
|
|
1334
|
+
let addressObject = {
|
|
1335
|
+
address: device.getAddress(),
|
|
1336
|
+
port: device.getPort()
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
let writeObject = {
|
|
1340
|
+
address: addressObject,
|
|
1341
|
+
objectId: {
|
|
1342
|
+
type: point.meta.objectId.type,
|
|
1343
|
+
instance: point.meta.objectId.instance,
|
|
1311
1344
|
},
|
|
1312
|
-
|
|
1313
|
-
{
|
|
1314
|
-
|
|
1315
|
-
|
|
1345
|
+
values: {
|
|
1346
|
+
property: {
|
|
1347
|
+
id: 85,
|
|
1348
|
+
index: point.meta.arrayIndex,
|
|
1316
1349
|
},
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1350
|
+
value: [
|
|
1351
|
+
{
|
|
1352
|
+
type: options.appTag,
|
|
1353
|
+
value: value,
|
|
1354
|
+
},
|
|
1355
|
+
],
|
|
1356
|
+
},
|
|
1357
|
+
options: {
|
|
1358
|
+
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1359
|
+
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1360
|
+
arrayIndex: point.meta.arrayIndex,
|
|
1361
|
+
priority: options.priority,
|
|
1362
|
+
},
|
|
1363
|
+
};
|
|
1326
1364
|
|
|
1327
|
-
|
|
1365
|
+
valuesArray.push(writeObject);
|
|
1366
|
+
} catch (e) {
|
|
1367
|
+
that.logOut("doWrite error: ", e);
|
|
1368
|
+
}
|
|
1328
1369
|
});
|
|
1329
1370
|
|
|
1330
1371
|
return that._writePropertyMultiple(valuesArray);
|
|
@@ -1348,7 +1389,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1348
1389
|
);
|
|
1349
1390
|
});
|
|
1350
1391
|
} catch (error) {
|
|
1351
|
-
that.logOut(error);
|
|
1392
|
+
that.logOut("_writePropertyMultiple error: ", error);
|
|
1352
1393
|
}
|
|
1353
1394
|
}
|
|
1354
1395
|
|
|
@@ -1370,7 +1411,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1370
1411
|
maxSegments: that.readPropertyMultipleOptions.maxSegments,
|
|
1371
1412
|
maxApdu: that.readPropertyMultipleOptions.maxApdu,
|
|
1372
1413
|
};
|
|
1373
|
-
this._readObjectList(device
|
|
1414
|
+
this._readObjectList(device, readOptions, (err, result) => {
|
|
1374
1415
|
if (!err) {
|
|
1375
1416
|
try {
|
|
1376
1417
|
resolve(result.values);
|
|
@@ -1437,6 +1478,17 @@ class BacnetClient extends EventEmitter {
|
|
|
1437
1478
|
});
|
|
1438
1479
|
}
|
|
1439
1480
|
|
|
1481
|
+
updatePointsList(json) {
|
|
1482
|
+
let that = this;
|
|
1483
|
+
json.deviceList.forEach(function (updatedDevice) {
|
|
1484
|
+
let foundIndex = that.deviceList.findIndex((ele) => ele.getDeviceId() == updatedDevice.deviceId);
|
|
1485
|
+
if (foundIndex == -1) {
|
|
1486
|
+
} else if (foundIndex !== -1) {
|
|
1487
|
+
that.deviceList[foundIndex].setPointsList(updatedDevice.pointsList);
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1440
1492
|
updateDeviceList(json) {
|
|
1441
1493
|
let that = this;
|
|
1442
1494
|
return new Promise(async function (resolve, reject) {
|
|
@@ -1622,7 +1674,6 @@ class BacnetClient extends EventEmitter {
|
|
|
1622
1674
|
|
|
1623
1675
|
async buildJsonObject(device) {
|
|
1624
1676
|
try {
|
|
1625
|
-
const address = device.address;
|
|
1626
1677
|
const pointList = device.getPointsList();
|
|
1627
1678
|
const requestMutex = new Mutex();
|
|
1628
1679
|
const promiseArray = [];
|
|
@@ -1633,12 +1684,12 @@ class BacnetClient extends EventEmitter {
|
|
|
1633
1684
|
|
|
1634
1685
|
for (const point of pointList) {
|
|
1635
1686
|
await requestMutex.acquire();
|
|
1636
|
-
|
|
1637
1687
|
let result;
|
|
1638
1688
|
if (device.getIsInitialQuery()) {
|
|
1639
|
-
result = await this._readObjectLite(device,
|
|
1689
|
+
result = await this._readObjectLite(device, point.value.type, point.value.instance);
|
|
1690
|
+
device.setIsInitialQuery(false);
|
|
1640
1691
|
} else {
|
|
1641
|
-
result = await this._readObjectFull(device,
|
|
1692
|
+
result = await this._readObjectFull(device, point.value.type, point.value.instance);
|
|
1642
1693
|
}
|
|
1643
1694
|
|
|
1644
1695
|
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
|
|