@bitpoolos/edge-bacnet 1.2.7 → 1.3.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 +76 -0
- package/README.md +20 -2
- package/bacnet_client.js +1662 -1572
- package/bacnet_device.js +122 -60
- package/bacnet_gateway.html +115 -71
- package/bacnet_gateway.js +165 -48
- package/bacnet_read.html +1025 -596
- package/bacnet_read.js +68 -84
- package/bacnet_server.js +187 -186
- package/bacnet_write.html +971 -738
- package/common.js +40 -28
- package/package.json +1 -1
- package/resources/bitArray.js +167 -0
- package/resources/node-bacstack-ts/dist/lib/asn1.js +16 -5
- package/resources/node-bacstack-ts/dist/lib/client.js +5 -6
- package/resources/style.css +321 -0
- package/treeBuilder.js +533 -0
package/bacnet_server.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const bacnet = require('./resources/node-bacstack-ts/dist/index.js');
|
|
2
2
|
const pjson = require('./package.json');
|
|
3
3
|
const baEnum = bacnet.enum;
|
|
4
|
-
const {Store_Config_Server, Read_Config_Sync_Server } = require('./common');
|
|
4
|
+
const { Store_Config_Server, Read_Config_Sync_Server } = require('./common');
|
|
5
5
|
|
|
6
6
|
class BacnetServer {
|
|
7
7
|
|
|
8
8
|
constructor(client, deviceId, nodeRedVersion) {
|
|
9
|
-
let that = this;
|
|
9
|
+
let that = this;
|
|
10
10
|
that.bacnetClient = client;
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
// object identifier init
|
|
13
13
|
that.objectIdNumber = {};
|
|
14
14
|
that.objectIdNumber[baEnum.ObjectType.ANALOG_VALUE] = 0;
|
|
@@ -19,55 +19,55 @@ class BacnetServer {
|
|
|
19
19
|
that.deviceId = deviceId;
|
|
20
20
|
that.vendorId = 1401;
|
|
21
21
|
that.objectList = [
|
|
22
|
-
{value: {type: baEnum.ObjectType.DEVICE, instance: that.deviceId}, type: 12}
|
|
22
|
+
{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }
|
|
23
23
|
];
|
|
24
24
|
that.objectStore = {
|
|
25
25
|
[baEnum.ObjectType.DEVICE]: {
|
|
26
|
-
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{value: {type: baEnum.ObjectType.DEVICE, instance: that.deviceId}, type: 12}],
|
|
27
|
-
[baEnum.PropertyIdentifier.OBJECT_LIST]: that.objectList,
|
|
28
|
-
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{value: 'Bitpool Edge BACnet Gateway', type: 7}],
|
|
29
|
-
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: 8, type: 9}],
|
|
30
|
-
[baEnum.PropertyIdentifier.DESCRIPTION]: [{value: 'Bitpool Edge BACnet gateway', type: 7}],
|
|
31
|
-
[baEnum.PropertyIdentifier.SYSTEM_STATUS]: [{value: 0, type: 9}],
|
|
32
|
-
[baEnum.PropertyIdentifier.VENDOR_NAME]:
|
|
33
|
-
[baEnum.PropertyIdentifier.VENDOR_IDENTIFIER]:
|
|
34
|
-
[baEnum.PropertyIdentifier.MODEL_NAME]:
|
|
35
|
-
[baEnum.PropertyIdentifier.FIRMWARE_REVISION]:
|
|
36
|
-
[baEnum.PropertyIdentifier.PROTOCOL_REVISION]:
|
|
37
|
-
[baEnum.PropertyIdentifier.PROTOCOL_VERSION]:
|
|
38
|
-
[baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION]:
|
|
39
|
-
[baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED]:
|
|
40
|
-
[baEnum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED]:
|
|
41
|
-
[baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED]:
|
|
42
|
-
[baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED]:
|
|
43
|
-
[baEnum.PropertyIdentifier.APDU_TIMEOUT]:
|
|
44
|
-
[baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES]:
|
|
45
|
-
[baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING]:
|
|
46
|
-
[baEnum.PropertyIdentifier.DATABASE_REVISION]:
|
|
47
|
-
[baEnum.PropertyIdentifier.PROPERTY_LIST]:
|
|
48
|
-
{value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
|
|
49
|
-
{value: baEnum.PropertyIdentifier.OBJECT_LIST, type: 9 },
|
|
50
|
-
{value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
|
|
51
|
-
{value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
|
|
52
|
-
{value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
|
|
53
|
-
{value: baEnum.PropertyIdentifier.SYSTEM_STATUS, type: 9 },
|
|
54
|
-
{value: baEnum.PropertyIdentifier.VENDOR_NAME, type: 9 },
|
|
55
|
-
{value: baEnum.PropertyIdentifier.VENDOR_IDENTIFIER, type: 9 },
|
|
56
|
-
{value: baEnum.PropertyIdentifier.MODEL_NAME, type: 9 },
|
|
57
|
-
{value: baEnum.PropertyIdentifier.FIRMWARE_REVISION, type: 9 },
|
|
58
|
-
{value: baEnum.PropertyIdentifier.PROTOCOL_REVISION, type: 9 },
|
|
59
|
-
{value: baEnum.PropertyIdentifier.PROTOCOL_VERSION, type: 9 },
|
|
60
|
-
{value: baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION, type: 9 },
|
|
61
|
-
{value: baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED, type: 9 },
|
|
62
|
-
{value: baEnum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED, type: 9 },
|
|
63
|
-
{value: baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED, type: 9 },
|
|
64
|
-
{value: baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED, type: 9 },
|
|
65
|
-
{value: baEnum.PropertyIdentifier.APDU_TIMEOUT, type: 9 },
|
|
66
|
-
{value: baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES, type: 9 },
|
|
67
|
-
{value: baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING, type: 9 },
|
|
68
|
-
{value: baEnum.PropertyIdentifier.DATABASE_REVISION, type: 9 },
|
|
26
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }],
|
|
27
|
+
[baEnum.PropertyIdentifier.OBJECT_LIST]: that.objectList,
|
|
28
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: 'Bitpool Edge BACnet Gateway', type: 7 }],
|
|
29
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: 8, type: 9 }],
|
|
30
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: 'Bitpool Edge BACnet gateway', type: 7 }],
|
|
31
|
+
[baEnum.PropertyIdentifier.SYSTEM_STATUS]: [{ value: 0, type: 9 }],
|
|
32
|
+
[baEnum.PropertyIdentifier.VENDOR_NAME]: [{ value: "Bitpool", type: 7 }],
|
|
33
|
+
[baEnum.PropertyIdentifier.VENDOR_IDENTIFIER]: [{ value: that.vendorId, type: 2 }],
|
|
34
|
+
[baEnum.PropertyIdentifier.MODEL_NAME]: [{ value: "bitpool-edge", type: 7 }],
|
|
35
|
+
[baEnum.PropertyIdentifier.FIRMWARE_REVISION]: [{ value: "Node-Red " + that.nodeRedVersion, type: 7 }],
|
|
36
|
+
[baEnum.PropertyIdentifier.PROTOCOL_REVISION]: [{ value: 19, type: 2 }],
|
|
37
|
+
[baEnum.PropertyIdentifier.PROTOCOL_VERSION]: [{ value: 0, type: 2 }],
|
|
38
|
+
[baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION]: [{ value: pjson.version, type: 7 }],
|
|
39
|
+
[baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED]: [{ value: { value: [0, 80, 0, 4, 4], bitsUsed: 40 }, type: 8 }],
|
|
40
|
+
[baEnum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED]: [{ value: { value: [0, 80, 0, 4, 4], bitsUsed: 40 }, type: 8 }],
|
|
41
|
+
[baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED]: [{ value: 1476, type: 2 }],
|
|
42
|
+
[baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED]: [{ value: 0, type: 9 }],
|
|
43
|
+
[baEnum.PropertyIdentifier.APDU_TIMEOUT]: [{ value: that.bacnetClient.config.apduTimeout, type: 2 }],
|
|
44
|
+
[baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES]: [{ value: 3, type: 2 }],
|
|
45
|
+
[baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING]: [{ value: 0, type: 12 }],
|
|
46
|
+
[baEnum.PropertyIdentifier.DATABASE_REVISION]: [{ value: 19, type: 2 }],
|
|
47
|
+
[baEnum.PropertyIdentifier.PROPERTY_LIST]: [
|
|
48
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
|
|
49
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_LIST, type: 9 },
|
|
50
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
|
|
51
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
|
|
52
|
+
{ value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
|
|
53
|
+
{ value: baEnum.PropertyIdentifier.SYSTEM_STATUS, type: 9 },
|
|
54
|
+
{ value: baEnum.PropertyIdentifier.VENDOR_NAME, type: 9 },
|
|
55
|
+
{ value: baEnum.PropertyIdentifier.VENDOR_IDENTIFIER, type: 9 },
|
|
56
|
+
{ value: baEnum.PropertyIdentifier.MODEL_NAME, type: 9 },
|
|
57
|
+
{ value: baEnum.PropertyIdentifier.FIRMWARE_REVISION, type: 9 },
|
|
58
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_REVISION, type: 9 },
|
|
59
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_VERSION, type: 9 },
|
|
60
|
+
{ value: baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION, type: 9 },
|
|
61
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED, type: 9 },
|
|
62
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED, type: 9 },
|
|
63
|
+
{ value: baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED, type: 9 },
|
|
64
|
+
{ value: baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED, type: 9 },
|
|
65
|
+
{ value: baEnum.PropertyIdentifier.APDU_TIMEOUT, type: 9 },
|
|
66
|
+
{ value: baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES, type: 9 },
|
|
67
|
+
{ value: baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING, type: 9 },
|
|
68
|
+
{ value: baEnum.PropertyIdentifier.DATABASE_REVISION, type: 9 },
|
|
69
69
|
],
|
|
70
|
-
},
|
|
70
|
+
},
|
|
71
71
|
[baEnum.ObjectType.ANALOG_VALUE]: [],
|
|
72
72
|
[baEnum.ObjectType.CHARACTERSTRING_VALUE]: [],
|
|
73
73
|
[baEnum.ObjectType.BINARY_VALUE]: []
|
|
@@ -75,14 +75,14 @@ class BacnetServer {
|
|
|
75
75
|
|
|
76
76
|
try {
|
|
77
77
|
let cachedData = JSON.parse(Read_Config_Sync_Server());
|
|
78
|
-
if(typeof cachedData == "object") {
|
|
78
|
+
if (typeof cachedData == "object") {
|
|
79
79
|
|
|
80
|
-
if(cachedData.objectList) that.objectList = cachedData.objectList;
|
|
81
|
-
if(cachedData.objectStore) {
|
|
80
|
+
if (cachedData.objectList) that.objectList = cachedData.objectList;
|
|
81
|
+
if (cachedData.objectStore) {
|
|
82
82
|
that.objectStore[baEnum.ObjectType.ANALOG_VALUE] = cachedData.objectStore[baEnum.ObjectType.ANALOG_VALUE];
|
|
83
83
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = cachedData.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE];
|
|
84
84
|
that.objectStore[baEnum.ObjectType.BINARY_VALUE] = cachedData.objectStore[baEnum.ObjectType.BINARY_VALUE];
|
|
85
|
-
}
|
|
85
|
+
}
|
|
86
86
|
}
|
|
87
87
|
} catch (error) {
|
|
88
88
|
//do nothing
|
|
@@ -100,27 +100,27 @@ class BacnetServer {
|
|
|
100
100
|
let responseObject = [];
|
|
101
101
|
|
|
102
102
|
try {
|
|
103
|
-
if(requestProps) {
|
|
103
|
+
if (requestProps) {
|
|
104
104
|
|
|
105
|
-
for(let i = 0; i < requestProps.length; i++) {
|
|
105
|
+
for (let i = 0; i < requestProps.length; i++) {
|
|
106
106
|
let prop = requestProps[i].properties[0].id;
|
|
107
107
|
let type = requestProps[i].objectId.type;
|
|
108
108
|
let instance = requestProps[i].objectId.instance;
|
|
109
109
|
let foundObject = that.getObjectMultiple(type, prop, instance, requestProps[i].properties);
|
|
110
110
|
|
|
111
|
-
if(foundObject !== null && foundObject !== undefined && foundObject !== "undefined") {
|
|
112
|
-
responseObject.push({objectId: {type: type, instance: instance}, values: foundObject});
|
|
111
|
+
if (foundObject !== null && foundObject !== undefined && foundObject !== "undefined") {
|
|
112
|
+
responseObject.push({ objectId: { type: type, instance: instance }, values: foundObject });
|
|
113
113
|
}
|
|
114
|
-
|
|
115
|
-
if(i == requestProps.length - 1) {
|
|
116
|
-
if(responseObject.length > 0) {
|
|
114
|
+
|
|
115
|
+
if (i == requestProps.length - 1) {
|
|
116
|
+
if (responseObject.length > 0) {
|
|
117
117
|
that.bacnetClient.client.readPropertyMultipleResponse(senderAddress, data.invokeId, responseObject);
|
|
118
118
|
} else {
|
|
119
119
|
that.bacnetClient.client.errorResponse(
|
|
120
|
-
data.address,
|
|
121
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
120
|
+
data.address,
|
|
121
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
122
122
|
data.invokeId,
|
|
123
|
-
baEnum.ErrorClass.PROPERTY,
|
|
123
|
+
baEnum.ErrorClass.PROPERTY,
|
|
124
124
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
125
125
|
);
|
|
126
126
|
}
|
|
@@ -128,12 +128,12 @@ class BacnetServer {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
} catch(e) {
|
|
131
|
+
} catch (e) {
|
|
132
132
|
that.bacnetClient.client.errorResponse(
|
|
133
|
-
data.address,
|
|
134
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
133
|
+
data.address,
|
|
134
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
135
135
|
data.invokeId,
|
|
136
|
-
baEnum.ErrorClass.PROPERTY,
|
|
136
|
+
baEnum.ErrorClass.PROPERTY,
|
|
137
137
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
138
138
|
);
|
|
139
139
|
}
|
|
@@ -150,23 +150,22 @@ class BacnetServer {
|
|
|
150
150
|
|
|
151
151
|
let responseObj = that.getObject(objectId, propId, objectInstance);
|
|
152
152
|
|
|
153
|
-
if(propId == baEnum.PropertyIdentifier.OBJECT_LIST &&
|
|
154
|
-
responseObj = [{value:that.objectList.length, type: 2}];
|
|
153
|
+
if (propId == baEnum.PropertyIdentifier.OBJECT_LIST && ((Date.now() - that.lastWhoIsRecived) / 1000) < 0.7) {
|
|
154
|
+
responseObj = [{ value: that.objectList.length, type: 2 }];
|
|
155
155
|
}
|
|
156
|
-
if(responseObj !== null && responseObj !== undefined && typeof responseObj !== "undefined") {
|
|
157
|
-
|
|
156
|
+
if (responseObj !== null && responseObj !== undefined && typeof responseObj !== "undefined") {
|
|
158
157
|
that.bacnetClient.client.readPropertyResponse(data.address, data.invokeId, objectId, data.request.property, responseObj);
|
|
159
158
|
} else {
|
|
160
159
|
that.bacnetClient.client.errorResponse(
|
|
161
|
-
data.address,
|
|
162
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY,
|
|
160
|
+
data.address,
|
|
161
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY,
|
|
163
162
|
data.invokeId,
|
|
164
|
-
baEnum.ErrorClass.PROPERTY,
|
|
163
|
+
baEnum.ErrorClass.PROPERTY,
|
|
165
164
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
166
165
|
);
|
|
167
166
|
}
|
|
168
|
-
} catch(e) {
|
|
169
|
-
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.log("Local BACnet device readProperty error: ", e);
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
});
|
|
@@ -177,7 +176,7 @@ class BacnetServer {
|
|
|
177
176
|
|
|
178
177
|
setDeviceName(nodeName) {
|
|
179
178
|
let that = this;
|
|
180
|
-
if(typeof nodeName == "string" && nodeName !== "") {
|
|
179
|
+
if (typeof nodeName == "string" && nodeName !== "") {
|
|
181
180
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_NAME][0].value = nodeName;
|
|
182
181
|
}
|
|
183
182
|
}
|
|
@@ -185,7 +184,7 @@ class BacnetServer {
|
|
|
185
184
|
addObject(name, value) {
|
|
186
185
|
let that = this;
|
|
187
186
|
let objectType = that.getBacnetObjectType(value);
|
|
188
|
-
if(name && objectType) {
|
|
187
|
+
if (name && objectType) {
|
|
189
188
|
let instanceNumber;
|
|
190
189
|
if (name.includes('|')) {
|
|
191
190
|
// split name, assign last part to instanceNumber and the rest to name
|
|
@@ -196,116 +195,118 @@ class BacnetServer {
|
|
|
196
195
|
}
|
|
197
196
|
let formattedName = name.replaceAll('.', '_');
|
|
198
197
|
formattedName = formattedName.replaceAll('/', '_');
|
|
199
|
-
if(objectType == "number") {
|
|
198
|
+
if (objectType == "number") {
|
|
200
199
|
let foundIndex = that.objectStore[baEnum.ObjectType.ANALOG_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
|
|
201
|
-
if(foundIndex == -1) {
|
|
200
|
+
if (foundIndex == -1) {
|
|
202
201
|
let objectId = that.getObjectIdentifier(baEnum.ObjectType.ANALOG_VALUE, instanceNumber);
|
|
203
202
|
that.objectStore[baEnum.ObjectType.ANALOG_VALUE].push({
|
|
204
|
-
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{value: formattedName, type: 7}],
|
|
205
|
-
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: baEnum.ObjectType.ANALOG_VALUE, type: 9}],
|
|
206
|
-
[baEnum.PropertyIdentifier.DESCRIPTION]: [{value: '', type: 7}],
|
|
207
|
-
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{value: {type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId}, type: 12}],
|
|
208
|
-
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{value: value, type: 4}],
|
|
209
|
-
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{value: 0, type: 8}],
|
|
210
|
-
[baEnum.PropertyIdentifier.EVENT_STATE]: [{value: 0, type: 9}],
|
|
211
|
-
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{value: 0, type: 9}],
|
|
212
|
-
[baEnum.PropertyIdentifier.UNITS]: [{value: 95, type: 9}],
|
|
213
|
-
[baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{value: 0, type: 9}],
|
|
214
|
-
[baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{value: value, type: 4}],
|
|
215
|
-
[baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{value: value, type: 4}],
|
|
216
|
-
[baEnum.PropertyIdentifier.RESOLUTION]: [{value: 0, type: 4}],
|
|
203
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
204
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.ANALOG_VALUE, type: 9 }],
|
|
205
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
206
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 }],
|
|
207
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 4 }],
|
|
208
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
209
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
210
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
211
|
+
[baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }],
|
|
212
|
+
[baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{ value: 0, type: 9 }],
|
|
213
|
+
[baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{ value: value, type: 4 }],
|
|
214
|
+
[baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{ value: value, type: 4 }],
|
|
215
|
+
[baEnum.PropertyIdentifier.RESOLUTION]: [{ value: 0, type: 4 }],
|
|
217
216
|
[baEnum.PropertyIdentifier.PROPERTY_LIST]:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
217
|
+
[
|
|
218
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
|
|
219
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
|
|
220
|
+
{ value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
|
|
221
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
|
|
222
|
+
{ value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
|
|
223
|
+
{ value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
|
|
224
|
+
{ value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
|
|
225
|
+
{ value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
|
|
226
|
+
{ value: baEnum.PropertyIdentifier.UNITS, type: 9 },
|
|
227
|
+
{ value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
|
|
228
|
+
{ value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
|
|
229
|
+
{ value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
|
|
230
|
+
{ value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
|
|
231
|
+
],
|
|
233
232
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
} else if(foundIndex !== -1) {
|
|
233
|
+
|
|
234
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 })
|
|
235
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
236
|
+
} else if (foundIndex !== -1) {
|
|
238
237
|
let foundObject = that.objectStore[baEnum.ObjectType.ANALOG_VALUE][foundIndex];
|
|
239
238
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
240
239
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
241
240
|
}
|
|
242
241
|
} else if (objectType == "boolean") {
|
|
243
242
|
let foundIndex = that.objectStore[baEnum.ObjectType.BINARY_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
|
|
244
|
-
if(foundIndex == -1) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
} else if(foundIndex !== -1) {
|
|
243
|
+
if (foundIndex == -1) {
|
|
244
|
+
let objectId = that.getObjectIdentifier(baEnum.ObjectType.BINARY_VALUE);
|
|
245
|
+
that.objectStore[baEnum.ObjectType.BINARY_VALUE].push({
|
|
246
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
247
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.BINARY_VALUE, type: 9 }],
|
|
248
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
249
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 }],
|
|
250
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 1 }],
|
|
251
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
252
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
253
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
254
|
+
[baEnum.PropertyIdentifier.ACTIVE_TEXT]: [{ value: 'ACTIVE', type: 7 }],
|
|
255
|
+
[baEnum.PropertyIdentifier.INACTIVE_TEXT]: [{ value: 'INACTIVE', type: 7 }],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 })
|
|
259
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
260
|
+
} else if (foundIndex !== -1) {
|
|
262
261
|
let foundObject = that.objectStore[baEnum.ObjectType.BINARY_VALUE][foundIndex];
|
|
263
262
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
264
263
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
265
264
|
}
|
|
266
|
-
} else if(objectType == "string") {
|
|
265
|
+
} else if (objectType == "string") {
|
|
267
266
|
let foundIndex = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
|
|
268
|
-
if(foundIndex == -1) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
} else if(foundIndex !== -1) {
|
|
267
|
+
if (foundIndex == -1) {
|
|
268
|
+
let objectId = that.getObjectIdentifier(baEnum.ObjectType.CHARACTERSTRING_VALUE);
|
|
269
|
+
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].push({
|
|
270
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
271
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.CHARACTERSTRING_VALUE, type: 9 }],
|
|
272
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
273
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 }],
|
|
274
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 7 }],
|
|
275
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
276
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
277
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
278
|
+
[baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }]
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 })
|
|
282
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
283
|
+
} else if (foundIndex !== -1) {
|
|
285
284
|
let foundObject = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE][foundIndex];
|
|
286
285
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
287
286
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
288
287
|
}
|
|
289
288
|
}
|
|
290
289
|
}
|
|
291
|
-
Store_Config_Server(JSON.stringify({objectList: that.objectList, objectStore: that.objectStore}));
|
|
290
|
+
Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
|
|
292
291
|
}
|
|
293
292
|
|
|
294
293
|
getObject(objectId, propId, instance) {
|
|
295
294
|
let that = this;
|
|
296
|
-
let objectGroup
|
|
295
|
+
let objectGroup = that.objectStore[objectId];
|
|
297
296
|
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
|
|
298
|
+
if (Array.isArray(objectGroup)) {
|
|
299
|
+
for (let i = 0; i < objectGroup.length; i++) {
|
|
300
300
|
let object = objectGroup[i];
|
|
301
|
-
if(object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
301
|
+
if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
302
302
|
let requestedProperty = object[propId];
|
|
303
|
-
if(requestedProperty !== null
|
|
303
|
+
if (requestedProperty !== null && requestedProperty !== undefined && typeof requestedProperty !== "undefined") {
|
|
304
304
|
return requestedProperty;
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
} else {
|
|
309
|
+
|
|
309
310
|
return objectGroup[propId];
|
|
310
311
|
}
|
|
311
312
|
|
|
@@ -314,75 +315,75 @@ class BacnetServer {
|
|
|
314
315
|
|
|
315
316
|
getObjectMultiple(objectId, propId, instance, properties) {
|
|
316
317
|
let that = this;
|
|
317
|
-
let objectGroup
|
|
318
|
+
let objectGroup = that.objectStore[objectId];
|
|
318
319
|
|
|
319
320
|
try {
|
|
320
|
-
|
|
321
|
-
if(Array.isArray(objectGroup)) {
|
|
322
|
-
for(let i = 0; i < objectGroup.length; i++) {
|
|
321
|
+
|
|
322
|
+
if (Array.isArray(objectGroup)) {
|
|
323
|
+
for (let i = 0; i < objectGroup.length; i++) {
|
|
323
324
|
let object = objectGroup[i];
|
|
324
|
-
if(object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
325
|
-
if(propId == baEnum.PropertyIdentifier.ALL) {
|
|
325
|
+
if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
326
|
+
if (propId == baEnum.PropertyIdentifier.ALL) {
|
|
326
327
|
let propList = [];
|
|
327
328
|
let keys = Object.keys(object);
|
|
328
|
-
keys.forEach(function(key) {
|
|
329
|
-
propList.push({property: {id: key, index: 0xFFFFFFFF}, value: object[key]});
|
|
329
|
+
keys.forEach(function (key) {
|
|
330
|
+
propList.push({ property: { id: key, index: 0xFFFFFFFF }, value: object[key] });
|
|
330
331
|
});
|
|
331
|
-
|
|
332
|
+
|
|
332
333
|
return propList;
|
|
333
334
|
|
|
334
|
-
} else if(properties && properties.length > 1) {
|
|
335
|
+
} else if (properties && properties.length > 1) {
|
|
335
336
|
let propList = [];
|
|
336
|
-
properties.forEach(function(p) {
|
|
337
|
-
if(object[p.id]){
|
|
338
|
-
propList.push({property: {id: p.id, index: 0xFFFFFFFF}, value: object[p.id]});
|
|
337
|
+
properties.forEach(function (p) {
|
|
338
|
+
if (object[p.id]) {
|
|
339
|
+
propList.push({ property: { id: p.id, index: 0xFFFFFFFF }, value: object[p.id] });
|
|
339
340
|
}
|
|
340
341
|
});
|
|
341
342
|
|
|
342
343
|
return propList;
|
|
343
|
-
|
|
344
|
+
|
|
344
345
|
} else {
|
|
345
|
-
return [{property: {id: propId, index: 0xFFFFFFFF}, value: object[propId]}];
|
|
346
|
+
return [{ property: { id: propId, index: 0xFFFFFFFF }, value: object[propId] }];
|
|
346
347
|
}
|
|
347
348
|
}
|
|
348
349
|
}
|
|
349
350
|
} else {
|
|
350
|
-
if(propId == baEnum.PropertyIdentifier.ALL) {
|
|
351
|
+
if (propId == baEnum.PropertyIdentifier.ALL) {
|
|
351
352
|
let propList = [];
|
|
352
353
|
let keys = Object.keys(objectGroup);
|
|
353
|
-
keys.forEach(function(key) {
|
|
354
|
-
propList.push({property: {id: key, index: 0xFFFFFFFF}, value: objectGroup[key]});
|
|
354
|
+
keys.forEach(function (key) {
|
|
355
|
+
propList.push({ property: { id: key, index: 0xFFFFFFFF }, value: objectGroup[key] });
|
|
355
356
|
});
|
|
356
|
-
|
|
357
|
+
|
|
357
358
|
return propList;
|
|
358
359
|
|
|
359
|
-
} else if(properties && properties.length > 1) {
|
|
360
|
+
} else if (properties && properties.length > 1) {
|
|
360
361
|
let propList = [];
|
|
361
|
-
properties.forEach(function(p) {
|
|
362
|
-
if(objectGroup[p.id]){
|
|
363
|
-
propList.push({property: {id: p.id, index: 0xFFFFFFFF}, value: objectGroup[p.id]});
|
|
362
|
+
properties.forEach(function (p) {
|
|
363
|
+
if (objectGroup[p.id]) {
|
|
364
|
+
propList.push({ property: { id: p.id, index: 0xFFFFFFFF }, value: objectGroup[p.id] });
|
|
364
365
|
}
|
|
365
366
|
});
|
|
366
367
|
|
|
367
368
|
return propList;
|
|
368
369
|
|
|
369
370
|
} else {
|
|
370
|
-
return [{property: {id: propId, index: 0xFFFFFFFF}, value: objectGroup[propId]}];
|
|
371
|
+
return [{ property: { id: propId, index: 0xFFFFFFFF }, value: objectGroup[propId] }];
|
|
371
372
|
}
|
|
372
373
|
}
|
|
373
374
|
|
|
374
|
-
} catch(e) {
|
|
375
|
+
} catch (e) {
|
|
375
376
|
//do nothing
|
|
376
377
|
}
|
|
377
|
-
|
|
378
|
+
|
|
378
379
|
return null;
|
|
379
380
|
}
|
|
380
381
|
|
|
381
382
|
clearServerPoints() {
|
|
382
383
|
let that = this;
|
|
383
|
-
|
|
384
|
+
|
|
384
385
|
that.objectList = [
|
|
385
|
-
{value: {type: baEnum.ObjectType.DEVICE, instance: that.deviceId}, type: 12}
|
|
386
|
+
{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }
|
|
386
387
|
];
|
|
387
388
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
388
389
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = [];
|
|
@@ -393,7 +394,7 @@ class BacnetServer {
|
|
|
393
394
|
that.objectIdNumber[baEnum.ObjectType.CHARACTERSTRING_VALUE] = 0;
|
|
394
395
|
that.objectIdNumber[baEnum.ObjectType.BINARY_VALUE] = 0;
|
|
395
396
|
|
|
396
|
-
Store_Config_Server(JSON.stringify({objectList: that.objectList, objectStore: that.objectStore}));
|
|
397
|
+
Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
|
|
397
398
|
}
|
|
398
399
|
|
|
399
400
|
clearServerPoint(json) {
|
|
@@ -453,7 +454,7 @@ class BacnetServer {
|
|
|
453
454
|
return new Promise(async function (resolve, reject) {
|
|
454
455
|
try {
|
|
455
456
|
// iterate analog value objects
|
|
456
|
-
if(that.objectStore[baEnum.ObjectType.ANALOG_VALUE] && that.objectStore[baEnum.ObjectType.ANALOG_VALUE].length > 0) {
|
|
457
|
+
if (that.objectStore[baEnum.ObjectType.ANALOG_VALUE] && that.objectStore[baEnum.ObjectType.ANALOG_VALUE].length > 0) {
|
|
457
458
|
that.objectStore[baEnum.ObjectType.ANALOG_VALUE].forEach((point) => {
|
|
458
459
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
459
460
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -467,7 +468,7 @@ class BacnetServer {
|
|
|
467
468
|
}
|
|
468
469
|
|
|
469
470
|
// iterate character string value objects
|
|
470
|
-
if(that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] && that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].length > 0) {
|
|
471
|
+
if (that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] && that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].length > 0) {
|
|
471
472
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].forEach((point) => {
|
|
472
473
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
473
474
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -481,7 +482,7 @@ class BacnetServer {
|
|
|
481
482
|
}
|
|
482
483
|
|
|
483
484
|
// iterate binary value objects
|
|
484
|
-
if(that.objectStore[baEnum.ObjectType.BINARY_VALUE] && that.objectStore[baEnum.ObjectType.BINARY_VALUE].length > 0) {
|
|
485
|
+
if (that.objectStore[baEnum.ObjectType.BINARY_VALUE] && that.objectStore[baEnum.ObjectType.BINARY_VALUE].length > 0) {
|
|
485
486
|
that.objectStore[baEnum.ObjectType.BINARY_VALUE].forEach((point) => {
|
|
486
487
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
487
488
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -512,7 +513,7 @@ class BacnetServer {
|
|
|
512
513
|
case "string":
|
|
513
514
|
return "string"
|
|
514
515
|
case "number":
|
|
515
|
-
return "number"
|
|
516
|
+
return "number"
|
|
516
517
|
case "boolean":
|
|
517
518
|
return "boolean"
|
|
518
519
|
default:
|