@bitpoolos/edge-bacnet 1.2.8 → 1.3.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 +105 -0
- package/README.md +23 -2
- package/bacnet_client.js +843 -803
- package/bacnet_device.js +132 -60
- package/bacnet_gateway.html +92 -76
- package/bacnet_gateway.js +161 -46
- package/bacnet_read.html +1048 -598
- package/bacnet_read.js +68 -84
- package/bacnet_server.js +270 -205
- package/bacnet_write.html +329 -24
- package/common.js +23 -5
- package/package.json +2 -2
- 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 +6 -7
- package/resources/style.css +321 -0
- package/treeBuilder.js +545 -0
package/bacnet_server.js
CHANGED
|
@@ -1,73 +1,85 @@
|
|
|
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');
|
|
5
|
-
|
|
4
|
+
const { Store_Config_Server, Read_Config_Sync_Server } = require('./common');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Class representing a BACnet Server.
|
|
8
|
+
*
|
|
9
|
+
* This class initializes a BACnet server with specified client, device ID, and Node-Red version.
|
|
10
|
+
* It provides methods to set device name, add objects, retrieve objects, clear server points, clear server point, and get server points.
|
|
11
|
+
*
|
|
12
|
+
* Simulates a BACnet IP device on a regular IP network
|
|
13
|
+
*
|
|
14
|
+
* @constructor
|
|
15
|
+
* @param {Object} client - The BACnet client object.
|
|
16
|
+
* @param {number} deviceId - The ID of the device.
|
|
17
|
+
* @param {string} nodeRedVersion - The version of Node-Red.
|
|
18
|
+
*/
|
|
6
19
|
class BacnetServer {
|
|
7
20
|
|
|
8
21
|
constructor(client, deviceId, nodeRedVersion) {
|
|
9
|
-
let that = this;
|
|
22
|
+
let that = this;
|
|
10
23
|
that.bacnetClient = client;
|
|
11
|
-
|
|
24
|
+
|
|
12
25
|
// object identifier init
|
|
13
26
|
that.objectIdNumber = {};
|
|
14
27
|
that.objectIdNumber[baEnum.ObjectType.ANALOG_VALUE] = 0;
|
|
15
28
|
that.objectIdNumber[baEnum.ObjectType.CHARACTERSTRING_VALUE] = 0;
|
|
16
29
|
that.objectIdNumber[baEnum.ObjectType.BINARY_VALUE] = 0;
|
|
17
|
-
|
|
18
30
|
that.nodeRedVersion = nodeRedVersion;
|
|
19
31
|
that.deviceId = deviceId;
|
|
20
32
|
that.vendorId = 1401;
|
|
21
33
|
that.objectList = [
|
|
22
|
-
{value: {type: baEnum.ObjectType.DEVICE, instance: that.deviceId}, type: 12}
|
|
34
|
+
{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }
|
|
23
35
|
];
|
|
36
|
+
|
|
24
37
|
that.objectStore = {
|
|
25
38
|
[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.
|
|
41
|
-
[baEnum.PropertyIdentifier.
|
|
42
|
-
[baEnum.PropertyIdentifier.
|
|
43
|
-
[baEnum.PropertyIdentifier.
|
|
44
|
-
[baEnum.PropertyIdentifier.
|
|
45
|
-
[baEnum.PropertyIdentifier.
|
|
46
|
-
[baEnum.PropertyIdentifier.
|
|
47
|
-
|
|
48
|
-
{value: baEnum.PropertyIdentifier.
|
|
49
|
-
{value: baEnum.PropertyIdentifier.
|
|
50
|
-
{value: baEnum.PropertyIdentifier.
|
|
51
|
-
{value: baEnum.PropertyIdentifier.
|
|
52
|
-
{value: baEnum.PropertyIdentifier.
|
|
53
|
-
{value: baEnum.PropertyIdentifier.
|
|
54
|
-
{value: baEnum.PropertyIdentifier.
|
|
55
|
-
{value: baEnum.PropertyIdentifier.
|
|
56
|
-
{value: baEnum.PropertyIdentifier.
|
|
57
|
-
{value: baEnum.PropertyIdentifier.
|
|
58
|
-
{value: baEnum.PropertyIdentifier.
|
|
59
|
-
{value: baEnum.PropertyIdentifier.
|
|
60
|
-
{value: baEnum.PropertyIdentifier.
|
|
61
|
-
{value: baEnum.PropertyIdentifier.
|
|
62
|
-
{value: baEnum.PropertyIdentifier.
|
|
63
|
-
{value: baEnum.PropertyIdentifier.
|
|
64
|
-
{value: baEnum.PropertyIdentifier.
|
|
65
|
-
{value: baEnum.PropertyIdentifier.
|
|
66
|
-
{value: baEnum.PropertyIdentifier.
|
|
67
|
-
{value: baEnum.PropertyIdentifier.
|
|
68
|
-
{value: baEnum.PropertyIdentifier.DATABASE_REVISION, type: 9 },
|
|
39
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }],
|
|
40
|
+
[baEnum.PropertyIdentifier.OBJECT_LIST]: that.objectList,
|
|
41
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: 'Bitpool Edge BACnet Gateway', type: 7 }],
|
|
42
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: 8, type: 9 }],
|
|
43
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: 'Bitpool Edge BACnet gateway', type: 7 }],
|
|
44
|
+
[baEnum.PropertyIdentifier.SYSTEM_STATUS]: [{ value: 0, type: 9 }],
|
|
45
|
+
[baEnum.PropertyIdentifier.VENDOR_NAME]: [{ value: "Bitpool", type: 7 }],
|
|
46
|
+
[baEnum.PropertyIdentifier.VENDOR_IDENTIFIER]: [{ value: that.vendorId, type: 2 }],
|
|
47
|
+
[baEnum.PropertyIdentifier.MODEL_NAME]: [{ value: "bitpool-edge", type: 7 }],
|
|
48
|
+
[baEnum.PropertyIdentifier.FIRMWARE_REVISION]: [{ value: "Node-Red " + that.nodeRedVersion, type: 7 }],
|
|
49
|
+
[baEnum.PropertyIdentifier.PROTOCOL_REVISION]: [{ value: 19, type: 2 }],
|
|
50
|
+
[baEnum.PropertyIdentifier.PROTOCOL_VERSION]: [{ value: 0, type: 2 }],
|
|
51
|
+
[baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION]: [{ value: pjson.version, type: 7 }],
|
|
52
|
+
[baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED]: [{ value: { value: [0, 10, 0, 32, 32], bitsUsed: 40 }, type: 8 }],
|
|
53
|
+
[baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED]: [{ value: 1476, type: 2 }],
|
|
54
|
+
[baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED]: [{ value: 0, type: 9 }],
|
|
55
|
+
[baEnum.PropertyIdentifier.APDU_TIMEOUT]: [{ value: that.bacnetClient.config.apduTimeout, type: 2 }],
|
|
56
|
+
[baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES]: [{ value: 3, type: 2 }],
|
|
57
|
+
[baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING]: [{ value: 0, type: 12 }],
|
|
58
|
+
[baEnum.PropertyIdentifier.DATABASE_REVISION]: [{ value: 19, type: 2 }],
|
|
59
|
+
[baEnum.PropertyIdentifier.PROPERTY_LIST]: [
|
|
60
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
|
|
61
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_LIST, type: 9 },
|
|
62
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
|
|
63
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
|
|
64
|
+
{ value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
|
|
65
|
+
{ value: baEnum.PropertyIdentifier.SYSTEM_STATUS, type: 9 },
|
|
66
|
+
{ value: baEnum.PropertyIdentifier.VENDOR_NAME, type: 9 },
|
|
67
|
+
{ value: baEnum.PropertyIdentifier.VENDOR_IDENTIFIER, type: 9 },
|
|
68
|
+
{ value: baEnum.PropertyIdentifier.MODEL_NAME, type: 9 },
|
|
69
|
+
{ value: baEnum.PropertyIdentifier.FIRMWARE_REVISION, type: 9 },
|
|
70
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_REVISION, type: 9 },
|
|
71
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_VERSION, type: 9 },
|
|
72
|
+
{ value: baEnum.PropertyIdentifier.APPLICATION_SOFTWARE_VERSION, type: 9 },
|
|
73
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_SERVICES_SUPPORTED, type: 9 },
|
|
74
|
+
{ value: baEnum.PropertyIdentifier.PROTOCOL_OBJECT_TYPES_SUPPORTED, type: 9 },
|
|
75
|
+
{ value: baEnum.PropertyIdentifier.MAX_APDU_LENGTH_ACCEPTED, type: 9 },
|
|
76
|
+
{ value: baEnum.PropertyIdentifier.SEGMENTATION_SUPPORTED, type: 9 },
|
|
77
|
+
{ value: baEnum.PropertyIdentifier.APDU_TIMEOUT, type: 9 },
|
|
78
|
+
{ value: baEnum.PropertyIdentifier.NUMBER_OF_APDU_RETRIES, type: 9 },
|
|
79
|
+
{ value: baEnum.PropertyIdentifier.DEVICE_ADDRESS_BINDING, type: 9 },
|
|
80
|
+
{ value: baEnum.PropertyIdentifier.DATABASE_REVISION, type: 9 },
|
|
69
81
|
],
|
|
70
|
-
},
|
|
82
|
+
},
|
|
71
83
|
[baEnum.ObjectType.ANALOG_VALUE]: [],
|
|
72
84
|
[baEnum.ObjectType.CHARACTERSTRING_VALUE]: [],
|
|
73
85
|
[baEnum.ObjectType.BINARY_VALUE]: []
|
|
@@ -75,14 +87,16 @@ class BacnetServer {
|
|
|
75
87
|
|
|
76
88
|
try {
|
|
77
89
|
let cachedData = JSON.parse(Read_Config_Sync_Server());
|
|
78
|
-
if(typeof cachedData == "object") {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
if (typeof cachedData == "object") {
|
|
91
|
+
if (cachedData.objectList) {
|
|
92
|
+
that.objectList = cachedData.objectList;
|
|
93
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
94
|
+
}
|
|
95
|
+
if (cachedData.objectStore) {
|
|
82
96
|
that.objectStore[baEnum.ObjectType.ANALOG_VALUE] = cachedData.objectStore[baEnum.ObjectType.ANALOG_VALUE];
|
|
83
97
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = cachedData.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE];
|
|
84
98
|
that.objectStore[baEnum.ObjectType.BINARY_VALUE] = cachedData.objectStore[baEnum.ObjectType.BINARY_VALUE];
|
|
85
|
-
}
|
|
99
|
+
}
|
|
86
100
|
}
|
|
87
101
|
} catch (error) {
|
|
88
102
|
//do nothing
|
|
@@ -94,98 +108,100 @@ class BacnetServer {
|
|
|
94
108
|
});
|
|
95
109
|
|
|
96
110
|
that.bacnetClient.client.on('readPropertyMultiple', (data) => {
|
|
97
|
-
|
|
98
111
|
let senderAddress = data.address;
|
|
99
112
|
let requestProps = data.request.properties;
|
|
100
113
|
let responseObject = [];
|
|
101
114
|
|
|
102
115
|
try {
|
|
103
|
-
if(requestProps) {
|
|
104
|
-
|
|
105
|
-
for(let i = 0; i < requestProps.length; i++) {
|
|
116
|
+
if (requestProps) {
|
|
117
|
+
for (let i = 0; i < requestProps.length; i++) {
|
|
106
118
|
let prop = requestProps[i].properties[0].id;
|
|
107
119
|
let type = requestProps[i].objectId.type;
|
|
108
120
|
let instance = requestProps[i].objectId.instance;
|
|
109
121
|
let foundObject = that.getObjectMultiple(type, prop, instance, requestProps[i].properties);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
responseObject.push({objectId: {type: type, instance: instance}, values: foundObject});
|
|
122
|
+
if (foundObject !== null && foundObject !== undefined && foundObject !== "undefined") {
|
|
123
|
+
responseObject.push({ objectId: { type: type, instance: instance }, values: foundObject });
|
|
113
124
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if(responseObject.length > 0) {
|
|
125
|
+
if (i == requestProps.length - 1) {
|
|
126
|
+
if (responseObject.length > 0) {
|
|
117
127
|
that.bacnetClient.client.readPropertyMultipleResponse(senderAddress, data.invokeId, responseObject);
|
|
118
128
|
} else {
|
|
119
129
|
that.bacnetClient.client.errorResponse(
|
|
120
|
-
data.address,
|
|
121
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
130
|
+
data.address,
|
|
131
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
122
132
|
data.invokeId,
|
|
123
|
-
baEnum.ErrorClass.PROPERTY,
|
|
133
|
+
baEnum.ErrorClass.PROPERTY,
|
|
124
134
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
125
135
|
);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
|
-
|
|
131
|
-
} catch(e) {
|
|
140
|
+
} catch (e) {
|
|
132
141
|
that.bacnetClient.client.errorResponse(
|
|
133
|
-
data.address,
|
|
134
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
142
|
+
data.address,
|
|
143
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
|
|
135
144
|
data.invokeId,
|
|
136
|
-
baEnum.ErrorClass.PROPERTY,
|
|
145
|
+
baEnum.ErrorClass.PROPERTY,
|
|
137
146
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
138
147
|
);
|
|
139
148
|
}
|
|
140
|
-
|
|
141
149
|
});
|
|
142
150
|
|
|
143
151
|
that.bacnetClient.client.on('readProperty', (data) => {
|
|
144
|
-
|
|
145
152
|
try {
|
|
146
|
-
|
|
147
153
|
let objectId = data.request.objectId.type;
|
|
148
154
|
let objectInstance = data.request.objectId.instance;
|
|
149
155
|
let propId = data.request.property.id.toString();
|
|
150
|
-
|
|
151
156
|
let responseObj = that.getObject(objectId, propId, objectInstance);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
if (propId == baEnum.PropertyIdentifier.OBJECT_LIST) {
|
|
158
|
+
if (data.request.property.index !== 0xFFFFFFFF) {
|
|
159
|
+
responseObj = responseObj[data.request.property.index];
|
|
160
|
+
}
|
|
155
161
|
}
|
|
156
|
-
if(responseObj !== null && responseObj !== undefined && typeof responseObj !== "undefined") {
|
|
157
|
-
|
|
158
|
-
that.bacnetClient.client.readPropertyResponse(data.address, data.invokeId, objectId, data.request.property, responseObj);
|
|
162
|
+
if (responseObj !== null && responseObj !== undefined && typeof responseObj !== "undefined") {
|
|
163
|
+
that.bacnetClient.client.readPropertyResponse(data.address, data.invokeId, data.request.objectId, data.request.property, responseObj);
|
|
159
164
|
} else {
|
|
160
165
|
that.bacnetClient.client.errorResponse(
|
|
161
|
-
data.address,
|
|
162
|
-
baEnum.ConfirmedServiceChoice.READ_PROPERTY,
|
|
166
|
+
data.address,
|
|
167
|
+
baEnum.ConfirmedServiceChoice.READ_PROPERTY,
|
|
163
168
|
data.invokeId,
|
|
164
|
-
baEnum.ErrorClass.PROPERTY,
|
|
169
|
+
baEnum.ErrorClass.PROPERTY,
|
|
165
170
|
baEnum.ErrorCode.UNKNOWN_PROPERTY
|
|
166
171
|
);
|
|
167
172
|
}
|
|
168
|
-
} catch(e) {
|
|
169
|
-
|
|
173
|
+
} catch (e) {
|
|
174
|
+
console.log("Local BACnet device readProperty error: ", e);
|
|
170
175
|
}
|
|
171
|
-
|
|
172
176
|
});
|
|
173
177
|
|
|
174
178
|
//do initial iAm broadcast when BACnet server starts
|
|
175
179
|
that.bacnetClient.client.iAmResponse(that.deviceId, baEnum.Segmentation.SEGMENTED_BOTH, that.vendorId);
|
|
176
180
|
}
|
|
177
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Set the name of the device.
|
|
184
|
+
*
|
|
185
|
+
* @param {string} nodeName - The new name for the device.
|
|
186
|
+
*/
|
|
178
187
|
setDeviceName(nodeName) {
|
|
179
188
|
let that = this;
|
|
180
|
-
if(typeof nodeName == "string" && nodeName !== "") {
|
|
189
|
+
if (typeof nodeName == "string" && nodeName !== "") {
|
|
181
190
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_NAME][0].value = nodeName;
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Adds a new object to the BacnetServer's object store based on the provided name and value.
|
|
196
|
+
*
|
|
197
|
+
* @param {string} name - The name of the object to be added.
|
|
198
|
+
* @param {number|boolean|string} value - The value of the object to be added.
|
|
199
|
+
* @returns {void}
|
|
200
|
+
*/
|
|
185
201
|
addObject(name, value) {
|
|
186
202
|
let that = this;
|
|
187
203
|
let objectType = that.getBacnetObjectType(value);
|
|
188
|
-
if(name && objectType) {
|
|
204
|
+
if (name && objectType) {
|
|
189
205
|
let instanceNumber;
|
|
190
206
|
if (name.includes('|')) {
|
|
191
207
|
// split name, assign last part to instanceNumber and the rest to name
|
|
@@ -196,111 +212,119 @@ class BacnetServer {
|
|
|
196
212
|
}
|
|
197
213
|
let formattedName = name.replaceAll('.', '_');
|
|
198
214
|
formattedName = formattedName.replaceAll('/', '_');
|
|
199
|
-
if(objectType == "number") {
|
|
215
|
+
if (objectType == "number") {
|
|
200
216
|
let foundIndex = that.objectStore[baEnum.ObjectType.ANALOG_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
|
|
201
|
-
if(foundIndex == -1) {
|
|
217
|
+
if (foundIndex == -1) {
|
|
202
218
|
let objectId = that.getObjectIdentifier(baEnum.ObjectType.ANALOG_VALUE, instanceNumber);
|
|
203
219
|
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}],
|
|
220
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
221
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.ANALOG_VALUE, type: 9 }],
|
|
222
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
223
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 }],
|
|
224
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 4 }],
|
|
225
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
226
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
227
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
228
|
+
[baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }],
|
|
229
|
+
[baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{ value: 0, type: 9 }],
|
|
230
|
+
[baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{ value: value, type: 4 }],
|
|
231
|
+
[baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{ value: value, type: 4 }],
|
|
232
|
+
[baEnum.PropertyIdentifier.RESOLUTION]: [{ value: 0, type: 4 }],
|
|
217
233
|
[baEnum.PropertyIdentifier.PROPERTY_LIST]:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
[
|
|
235
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
|
|
236
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
|
|
237
|
+
{ value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
|
|
238
|
+
{ value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
|
|
239
|
+
{ value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
|
|
240
|
+
{ value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
|
|
241
|
+
{ value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
|
|
242
|
+
{ value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
|
|
243
|
+
{ value: baEnum.PropertyIdentifier.UNITS, type: 9 },
|
|
244
|
+
{ value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
|
|
245
|
+
{ value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
|
|
246
|
+
{ value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
|
|
247
|
+
{ value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
|
|
248
|
+
],
|
|
233
249
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
} else if(foundIndex !== -1) {
|
|
250
|
+
|
|
251
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 })
|
|
252
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
253
|
+
} else if (foundIndex !== -1) {
|
|
238
254
|
let foundObject = that.objectStore[baEnum.ObjectType.ANALOG_VALUE][foundIndex];
|
|
239
255
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
240
256
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
241
257
|
}
|
|
242
258
|
} else if (objectType == "boolean") {
|
|
243
259
|
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) {
|
|
260
|
+
if (foundIndex == -1) {
|
|
261
|
+
let objectId = that.getObjectIdentifier(baEnum.ObjectType.BINARY_VALUE);
|
|
262
|
+
that.objectStore[baEnum.ObjectType.BINARY_VALUE].push({
|
|
263
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
264
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.BINARY_VALUE, type: 9 }],
|
|
265
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
266
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 }],
|
|
267
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 1 }],
|
|
268
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
269
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
270
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
271
|
+
[baEnum.PropertyIdentifier.ACTIVE_TEXT]: [{ value: 'ACTIVE', type: 7 }],
|
|
272
|
+
[baEnum.PropertyIdentifier.INACTIVE_TEXT]: [{ value: 'INACTIVE', type: 7 }],
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 })
|
|
276
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
277
|
+
} else if (foundIndex !== -1) {
|
|
262
278
|
let foundObject = that.objectStore[baEnum.ObjectType.BINARY_VALUE][foundIndex];
|
|
263
279
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
264
280
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
265
281
|
}
|
|
266
|
-
} else if(objectType == "string") {
|
|
282
|
+
} else if (objectType == "string") {
|
|
267
283
|
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) {
|
|
284
|
+
if (foundIndex == -1) {
|
|
285
|
+
let objectId = that.getObjectIdentifier(baEnum.ObjectType.CHARACTERSTRING_VALUE);
|
|
286
|
+
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].push({
|
|
287
|
+
[baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
|
|
288
|
+
[baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.CHARACTERSTRING_VALUE, type: 9 }],
|
|
289
|
+
[baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
|
|
290
|
+
[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 }],
|
|
291
|
+
[baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 7 }],
|
|
292
|
+
[baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
|
|
293
|
+
[baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
|
|
294
|
+
[baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
|
|
295
|
+
[baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }]
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
that.objectList.push({ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 })
|
|
299
|
+
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
300
|
+
} else if (foundIndex !== -1) {
|
|
285
301
|
let foundObject = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE][foundIndex];
|
|
286
302
|
foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
|
|
287
303
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
288
304
|
}
|
|
289
305
|
}
|
|
290
306
|
}
|
|
291
|
-
Store_Config_Server(JSON.stringify({objectList: that.objectList, objectStore: that.objectStore}));
|
|
307
|
+
Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
|
|
292
308
|
}
|
|
293
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Retrieves a specific property of an object based on the object ID, property ID, and instance number.
|
|
312
|
+
*
|
|
313
|
+
* @param {number} objectId - The ID of the object type.
|
|
314
|
+
* @param {number} propId - The ID of the property to retrieve.
|
|
315
|
+
* @param {number} instance - The instance number of the object.
|
|
316
|
+
* @returns {any} The requested property value if found, otherwise null.
|
|
317
|
+
*/
|
|
294
318
|
getObject(objectId, propId, instance) {
|
|
295
319
|
let that = this;
|
|
296
|
-
let objectGroup
|
|
320
|
+
let objectGroup = that.objectStore[objectId];
|
|
297
321
|
|
|
298
|
-
if(Array.isArray(objectGroup)) {
|
|
299
|
-
for(let i = 0; i < objectGroup.length; i++) {
|
|
322
|
+
if (Array.isArray(objectGroup)) {
|
|
323
|
+
for (let i = 0; i < objectGroup.length; i++) {
|
|
300
324
|
let object = objectGroup[i];
|
|
301
|
-
if(object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
325
|
+
if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
302
326
|
let requestedProperty = object[propId];
|
|
303
|
-
if(requestedProperty !== null
|
|
327
|
+
if (requestedProperty !== null && requestedProperty !== undefined && typeof requestedProperty !== "undefined") {
|
|
304
328
|
return requestedProperty;
|
|
305
329
|
}
|
|
306
330
|
}
|
|
@@ -312,77 +336,91 @@ class BacnetServer {
|
|
|
312
336
|
return null;
|
|
313
337
|
}
|
|
314
338
|
|
|
339
|
+
/**
|
|
340
|
+
* Retrieves the properties of a specific object instance from the objectStore based on the provided parameters.
|
|
341
|
+
*
|
|
342
|
+
* @param {number} objectId - The type of the object to retrieve.
|
|
343
|
+
* @param {number} propId - The property identifier to retrieve.
|
|
344
|
+
* @param {number} instance - The instance number of the object to retrieve.
|
|
345
|
+
* @param {Array} properties - An array of additional properties to retrieve along with the main property.
|
|
346
|
+
* @returns {Array|null} - An array of properties with values for the specified object instance, or null if not found.
|
|
347
|
+
*/
|
|
315
348
|
getObjectMultiple(objectId, propId, instance, properties) {
|
|
316
349
|
let that = this;
|
|
317
|
-
let objectGroup
|
|
350
|
+
let objectGroup = that.objectStore[objectId];
|
|
318
351
|
|
|
319
352
|
try {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
for(let i = 0; i < objectGroup.length; i++) {
|
|
353
|
+
if (Array.isArray(objectGroup)) {
|
|
354
|
+
for (let i = 0; i < objectGroup.length; i++) {
|
|
323
355
|
let object = objectGroup[i];
|
|
324
|
-
if(object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
325
|
-
if(propId == baEnum.PropertyIdentifier.ALL) {
|
|
356
|
+
if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
357
|
+
if (propId == baEnum.PropertyIdentifier.ALL) {
|
|
326
358
|
let propList = [];
|
|
327
359
|
let keys = Object.keys(object);
|
|
328
|
-
keys.forEach(function(key) {
|
|
329
|
-
propList.push({property: {id: key, index: 0xFFFFFFFF}, value: object[key]});
|
|
360
|
+
keys.forEach(function (key) {
|
|
361
|
+
propList.push({ property: { id: key, index: 0xFFFFFFFF }, value: object[key] });
|
|
330
362
|
});
|
|
331
|
-
|
|
363
|
+
|
|
332
364
|
return propList;
|
|
333
365
|
|
|
334
|
-
} else if(properties && properties.length > 1) {
|
|
366
|
+
} else if (properties && properties.length > 1) {
|
|
335
367
|
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]});
|
|
368
|
+
properties.forEach(function (p) {
|
|
369
|
+
if (object[p.id]) {
|
|
370
|
+
propList.push({ property: { id: p.id, index: 0xFFFFFFFF }, value: object[p.id] });
|
|
339
371
|
}
|
|
340
372
|
});
|
|
341
373
|
|
|
342
374
|
return propList;
|
|
343
|
-
|
|
375
|
+
|
|
344
376
|
} else {
|
|
345
|
-
return [{property: {id: propId, index: 0xFFFFFFFF}, value: object[propId]}];
|
|
377
|
+
return [{ property: { id: propId, index: 0xFFFFFFFF }, value: object[propId] }];
|
|
346
378
|
}
|
|
347
379
|
}
|
|
348
380
|
}
|
|
349
381
|
} else {
|
|
350
|
-
if(propId == baEnum.PropertyIdentifier.ALL) {
|
|
382
|
+
if (propId == baEnum.PropertyIdentifier.ALL) {
|
|
351
383
|
let propList = [];
|
|
352
384
|
let keys = Object.keys(objectGroup);
|
|
353
|
-
keys.forEach(function(key) {
|
|
354
|
-
propList.push({property: {id: key, index: 0xFFFFFFFF}, value: objectGroup[key]});
|
|
385
|
+
keys.forEach(function (key) {
|
|
386
|
+
propList.push({ property: { id: key, index: 0xFFFFFFFF }, value: objectGroup[key] });
|
|
355
387
|
});
|
|
356
|
-
|
|
388
|
+
|
|
357
389
|
return propList;
|
|
358
390
|
|
|
359
|
-
} else if(properties && properties.length > 1) {
|
|
391
|
+
} else if (properties && properties.length > 1) {
|
|
360
392
|
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]});
|
|
393
|
+
properties.forEach(function (p) {
|
|
394
|
+
if (objectGroup[p.id]) {
|
|
395
|
+
propList.push({ property: { id: p.id, index: 0xFFFFFFFF }, value: objectGroup[p.id] });
|
|
364
396
|
}
|
|
365
397
|
});
|
|
366
398
|
|
|
367
399
|
return propList;
|
|
368
400
|
|
|
369
401
|
} else {
|
|
370
|
-
return [{property: {id: propId, index: 0xFFFFFFFF}, value: objectGroup[propId]}];
|
|
402
|
+
return [{ property: { id: propId, index: 0xFFFFFFFF }, value: objectGroup[propId] }];
|
|
371
403
|
}
|
|
372
404
|
}
|
|
373
405
|
|
|
374
|
-
} catch(e) {
|
|
406
|
+
} catch (e) {
|
|
375
407
|
//do nothing
|
|
376
408
|
}
|
|
377
|
-
|
|
409
|
+
|
|
378
410
|
return null;
|
|
379
411
|
}
|
|
380
412
|
|
|
413
|
+
/**
|
|
414
|
+
* Clear all server points by resetting the object lists and object store.
|
|
415
|
+
* This method resets the object list for the device, clears the character string values,
|
|
416
|
+
* and clears the analog values. It also resets the object id numbers for analog, character string, and binary values.
|
|
417
|
+
* Finally, it stores the updated object list and object store in the server configuration.
|
|
418
|
+
*/
|
|
381
419
|
clearServerPoints() {
|
|
382
420
|
let that = this;
|
|
383
|
-
|
|
421
|
+
|
|
384
422
|
that.objectList = [
|
|
385
|
-
{value: {type: baEnum.ObjectType.DEVICE, instance: that.deviceId}, type: 12}
|
|
423
|
+
{ value: { type: baEnum.ObjectType.DEVICE, instance: that.deviceId }, type: 12 }
|
|
386
424
|
];
|
|
387
425
|
that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
|
|
388
426
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = [];
|
|
@@ -393,9 +431,17 @@ class BacnetServer {
|
|
|
393
431
|
that.objectIdNumber[baEnum.ObjectType.CHARACTERSTRING_VALUE] = 0;
|
|
394
432
|
that.objectIdNumber[baEnum.ObjectType.BINARY_VALUE] = 0;
|
|
395
433
|
|
|
396
|
-
Store_Config_Server(JSON.stringify({objectList: that.objectList, objectStore: that.objectStore}));
|
|
434
|
+
Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
|
|
397
435
|
}
|
|
398
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Removes a server point from the objectStore and objectList based on the provided JSON data.
|
|
439
|
+
*
|
|
440
|
+
* @param {Object} json - The JSON data containing information about the server point to be removed.
|
|
441
|
+
* @param {string} json.body.type - The type of the server point ('SV' for CharacterString, 'BV' for BinaryValue, default is AnalogValue).
|
|
442
|
+
* @param {number} json.body.instance - The instance number of the server point to be removed.
|
|
443
|
+
* @returns {Promise<boolean>} A Promise that resolves to true if the server point is successfully removed, otherwise rejects with an error.
|
|
444
|
+
*/
|
|
399
445
|
clearServerPoint(json) {
|
|
400
446
|
let that = this;
|
|
401
447
|
return new Promise(async function (resolve, reject) {
|
|
@@ -446,6 +492,17 @@ class BacnetServer {
|
|
|
446
492
|
});
|
|
447
493
|
}
|
|
448
494
|
|
|
495
|
+
/**
|
|
496
|
+
* Retrieves all server points from the BacnetServer objectStore.
|
|
497
|
+
* Points include Analog Value, Character String Value, and Binary Value objects.
|
|
498
|
+
* Each point is represented as an object with properties:
|
|
499
|
+
* - name: The name of the object.
|
|
500
|
+
* - type: The type of the object (AV for Analog Value, SV for Character String Value, BV for Binary Value).
|
|
501
|
+
* - instance: The instance number of the object.
|
|
502
|
+
*
|
|
503
|
+
* @returns {Promise<Array>} A promise that resolves with an array of points sorted by instance number.
|
|
504
|
+
* @throws {Error} If an error occurs during the retrieval process.
|
|
505
|
+
*/
|
|
449
506
|
getServerPoints() {
|
|
450
507
|
let that = this;
|
|
451
508
|
let points = [];
|
|
@@ -453,7 +510,7 @@ class BacnetServer {
|
|
|
453
510
|
return new Promise(async function (resolve, reject) {
|
|
454
511
|
try {
|
|
455
512
|
// iterate analog value objects
|
|
456
|
-
if(that.objectStore[baEnum.ObjectType.ANALOG_VALUE] && that.objectStore[baEnum.ObjectType.ANALOG_VALUE].length > 0) {
|
|
513
|
+
if (that.objectStore[baEnum.ObjectType.ANALOG_VALUE] && that.objectStore[baEnum.ObjectType.ANALOG_VALUE].length > 0) {
|
|
457
514
|
that.objectStore[baEnum.ObjectType.ANALOG_VALUE].forEach((point) => {
|
|
458
515
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
459
516
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -467,7 +524,7 @@ class BacnetServer {
|
|
|
467
524
|
}
|
|
468
525
|
|
|
469
526
|
// iterate character string value objects
|
|
470
|
-
if(that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] && that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].length > 0) {
|
|
527
|
+
if (that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] && that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].length > 0) {
|
|
471
528
|
that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].forEach((point) => {
|
|
472
529
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
473
530
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -481,7 +538,7 @@ class BacnetServer {
|
|
|
481
538
|
}
|
|
482
539
|
|
|
483
540
|
// iterate binary value objects
|
|
484
|
-
if(that.objectStore[baEnum.ObjectType.BINARY_VALUE] && that.objectStore[baEnum.ObjectType.BINARY_VALUE].length > 0) {
|
|
541
|
+
if (that.objectStore[baEnum.ObjectType.BINARY_VALUE] && that.objectStore[baEnum.ObjectType.BINARY_VALUE].length > 0) {
|
|
485
542
|
that.objectStore[baEnum.ObjectType.BINARY_VALUE].forEach((point) => {
|
|
486
543
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
487
544
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
@@ -501,10 +558,12 @@ class BacnetServer {
|
|
|
501
558
|
});
|
|
502
559
|
}
|
|
503
560
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Determines the BACnet object type based on the provided value.
|
|
563
|
+
*
|
|
564
|
+
* @param {any} value - The value to determine the BACnet object type for.
|
|
565
|
+
* @returns {string|null} The BACnet object type as a string ('string', 'number', 'boolean') or null if the type is not recognized.
|
|
566
|
+
*/
|
|
508
567
|
getBacnetObjectType(value) {
|
|
509
568
|
let type = typeof value;
|
|
510
569
|
|
|
@@ -512,7 +571,7 @@ class BacnetServer {
|
|
|
512
571
|
case "string":
|
|
513
572
|
return "string"
|
|
514
573
|
case "number":
|
|
515
|
-
return "number"
|
|
574
|
+
return "number"
|
|
516
575
|
case "boolean":
|
|
517
576
|
return "boolean"
|
|
518
577
|
default:
|
|
@@ -520,6 +579,13 @@ class BacnetServer {
|
|
|
520
579
|
}
|
|
521
580
|
}
|
|
522
581
|
|
|
582
|
+
/**
|
|
583
|
+
* Returns the object identifier for the given type and instance number.
|
|
584
|
+
*
|
|
585
|
+
* @param {string} type - The type of the object.
|
|
586
|
+
* @param {number} instanceNumber - The instance number of the object.
|
|
587
|
+
* @returns {number} The object identifier.
|
|
588
|
+
*/
|
|
523
589
|
getObjectIdentifier(type, instanceNumber) {
|
|
524
590
|
let that = this;
|
|
525
591
|
// manual instance numbering
|
|
@@ -532,7 +598,6 @@ class BacnetServer {
|
|
|
532
598
|
that.objectIdNumber[type]++;
|
|
533
599
|
return objectId;
|
|
534
600
|
}
|
|
535
|
-
|
|
536
601
|
}
|
|
537
602
|
|
|
538
603
|
module.exports = { BacnetServer };
|