@halsystems/red-bacnet 1.1.0 → 1.1.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1]
4
+ ### Added
5
+ - Unit test for BACnet string points
6
+
7
+ ### Fixed
8
+ - Reading offline device points run infinitely
9
+ - Unit test failure
10
+
3
11
  ## [1.1.0]
4
12
  ### Changed
5
13
  - Implemented auto resize batch size when querying using readPropertyMultiple to improve performance
package/common/bacnet.js CHANGED
@@ -115,7 +115,6 @@ module.exports = {
115
115
  if (item?.type === 105) break
116
116
 
117
117
  result.push(item);
118
- console.log(item)
119
118
  } catch (err) {
120
119
  void err
121
120
  break;
@@ -155,13 +154,15 @@ module.exports = {
155
154
  * maximum concurrent point to read in single read mode
156
155
  * @param {number} singleReadFailedRetry
157
156
  * retry times for single read failed
157
+ * @param {number} concurrentTaskDelay
158
+ * delay between concurrent tasks
158
159
  * @returns array of objects
159
160
  * eg: [{type: 12, value: {type: 8, instance: 123}, ...],
160
161
  * @async
161
162
  */
162
163
  smartReadProperty: async function (
163
164
  client, device, reqArr, readMethod = 1, maxConcurrentSinglePointRead = 5,
164
- singleReadFailedRetry = 5
165
+ singleReadFailedRetry = 5, concurrentTaskDelay = 50
165
166
  ) {
166
167
  /* reqArr example
167
168
  [{
@@ -182,8 +183,11 @@ module.exports = {
182
183
  batchSizes.add(20);
183
184
  else {
184
185
  const perValueBytes = [30] // typical numeric point is 17 byte
185
- for (let x = 0; x < perValueBytes.length; x++)
186
- batchSizes.add(Math.trunc(device.maxApdu / perValueBytes[x]))
186
+ for (let x = 0; x < perValueBytes.length; x++) {
187
+ let batchSize = Math.trunc(device.maxApdu / perValueBytes[x])
188
+ if (batchSize > 0)
189
+ batchSizes.add(batchSize)
190
+ }
187
191
  }
188
192
  }
189
193
 
@@ -261,7 +265,6 @@ module.exports = {
261
265
  if (!success) {
262
266
  let failedCount = 0
263
267
  let result_single = []
264
-
265
268
  const dummyEventEmitter = new EventEmitter();
266
269
  const tasks = reqArr.slice(reqArrIndexNext).flatMap((req, x) =>
267
270
  req.properties.map((prop, y) => ({
@@ -285,7 +288,7 @@ module.exports = {
285
288
  return value;
286
289
  } catch (err) {
287
290
  failedCount++;
288
- if (readMethod < 1 && failedCount >= singleReadFailedRetry)
291
+ if (failedCount >= singleReadFailedRetry)
289
292
  throw err
290
293
  }
291
294
  }
@@ -293,7 +296,7 @@ module.exports = {
293
296
  );
294
297
 
295
298
  try {
296
- await concurrentTasks(dummyEventEmitter, tasks, maxConcurrentSinglePointRead);
299
+ await concurrentTasks(dummyEventEmitter, tasks, maxConcurrentSinglePointRead, concurrentTaskDelay);
297
300
  } catch (err) {
298
301
  void err
299
302
  }
@@ -342,9 +345,14 @@ module.exports = {
342
345
  * @param {EventEmitter} eventEmitter
343
346
  * @param {number} maxConcurrentWrite
344
347
  * maximum concurrent point to write
348
+ * @param {number} concurrentTaskDelay
349
+ * delay between concurrent tasks
345
350
  * @async
346
351
  */
347
- smartWriteProperty: async function (client, device, writePoints, eventEmitter, maxConcurrentWrite) {
352
+ smartWriteProperty: async function (
353
+ client, device, writePoints, eventEmitter, maxConcurrentWrite,
354
+ concurrentTaskDelay = 50
355
+ ) {
348
356
  const entries = Object.entries(writePoints);
349
357
 
350
358
  // current writePropertyMultiple will throw ERR_TIMEOUT if any of the write fails
@@ -370,7 +378,7 @@ module.exports = {
370
378
  }
371
379
  }));
372
380
 
373
- await concurrentTasks(eventEmitter, tasks, maxConcurrentWrite);
381
+ await concurrentTasks(eventEmitter, tasks, maxConcurrentWrite, concurrentTaskDelay);
374
382
 
375
383
  // write properties multiples example
376
384
  // const values = [
@@ -17,10 +17,13 @@ module.exports = {
17
17
  * @param {EventEmitter} eventEmitter - The event emitter to emit events to.
18
18
  * @param {Array} tasks - The list of tasks to execute.
19
19
  * @param {number} maxConcurrent - The maximum number of concurrent tasks.
20
+ * @param {number} concurrentTaskDelay - The delay between concurrent tasks.
20
21
  * @returns {Promise<Array>} - A promise that resolves with an array of results.
21
22
  * @async
22
23
  */
23
- concurrentTasks: async function (eventEmitter, tasks, maxConcurrent) {
24
+ concurrentTasks: async function (
25
+ eventEmitter, tasks, maxConcurrent, concurrentTaskDelay = 50
26
+ ) {
24
27
  const executing = new Set();
25
28
  const results = [];
26
29
 
@@ -44,7 +47,8 @@ module.exports = {
44
47
  await Promise.race(executing);
45
48
  }
46
49
 
47
- await delay(50)
50
+ if (concurrentTaskDelay > 0)
51
+ await delay(concurrentTaskDelay)
48
52
  }
49
53
 
50
54
  await Promise.allSettled(executing);
@@ -53,7 +53,8 @@ module.exports = {
53
53
 
54
54
  constructor(
55
55
  client, eventEmitter, inputDevices, discoverMode, readMethod, groupExportDeviceCount,
56
- maxConcurrentDeviceRead, maxConcurrentSinglePointRead, name = 'discover point'
56
+ maxConcurrentDeviceRead, maxConcurrentSinglePointRead, concurrentTaskDelay = 50,
57
+ name = 'discover point'
57
58
  ) {
58
59
  super();
59
60
  this.client = client
@@ -64,6 +65,7 @@ module.exports = {
64
65
  this.groupExportDeviceCount = groupExportDeviceCount
65
66
  this.maxConcurrentDeviceRead = maxConcurrentDeviceRead
66
67
  this.maxConcurrentSinglePointRead = maxConcurrentSinglePointRead
68
+ this.concurrentTaskDelay = concurrentTaskDelay
67
69
  this.name = name
68
70
  }
69
71
 
@@ -194,7 +196,7 @@ module.exports = {
194
196
 
195
197
  return await readPoints(
196
198
  d, objectListFinal, discoverPointEvent, this.name, this.client, this.readMethod,
197
- this.maxConcurrentSinglePointRead
199
+ this.maxConcurrentSinglePointRead, this.concurrentTaskDelay
198
200
  );
199
201
  } catch (error) {
200
202
  this.eventEmitter.emit(EVENT_ERROR, errMsg(this.name, `Error reading ${d.deviceName} points`, error));
@@ -237,7 +239,8 @@ module.exports = {
237
239
 
238
240
  // ---------------------------------- functions ----------------------------------
239
241
  const readPoints = async (
240
- device, objects, eventEmitter, name, client, readMethod, maxConcurrentSinglePointRead
242
+ device, objects, eventEmitter, name, client, readMethod, maxConcurrentSinglePointRead,
243
+ concurrentTaskDelay
241
244
  ) => {
242
245
  const points = [];
243
246
 
@@ -258,7 +261,7 @@ const readPoints = async (
258
261
  try {
259
262
  // First request - get basic properties
260
263
  const result = await smartReadProperty(
261
- client, device, reqArr, readMethod, maxConcurrentSinglePointRead, 50
264
+ client, device, reqArr, readMethod, maxConcurrentSinglePointRead, 50, concurrentTaskDelay
262
265
  );
263
266
 
264
267
  // Process basic properties first
@@ -279,7 +282,7 @@ const readPoints = async (
279
282
  try {
280
283
  // Force use single read on state text to reduce loss especially long text
281
284
  const stateTextResult = await smartReadProperty(
282
- client, device, stateTextReqArr, 0, 1, 50
285
+ client, device, stateTextReqArr, 0, 1, 50, concurrentTaskDelay
283
286
  );
284
287
 
285
288
  // Update points with STATE_TEXT
@@ -374,7 +377,7 @@ const setPointValues = (point, i) => {
374
377
 
375
378
  const processValue = (value, facets) => {
376
379
  if (value?.errorClass != null && value?.errorCode != null) return null;
377
- const match = facets.match(/precision:(\d+)/);
380
+ const match = facets?.match(/precision:(\d+)/);
378
381
  const precision = match ? +match[1] : null;
379
382
 
380
383
  if (typeof value === 'number')
@@ -382,4 +385,4 @@ const processValue = (value, facets) => {
382
385
  else
383
386
  return value
384
387
 
385
- };
388
+ };
@@ -23,7 +23,7 @@ module.exports = {
23
23
 
24
24
  constructor(
25
25
  client, eventEmitter, devices, points, readMethod, maxConcurrentDeviceRead = 2,
26
- maxConcurrentSinglePointRead = 5, name = 'read point'
26
+ maxConcurrentSinglePointRead = 5, concurrentTaskDelay = 50, name = 'read point'
27
27
  ) {
28
28
  super();
29
29
  this.client = client
@@ -33,6 +33,7 @@ module.exports = {
33
33
  this.readMethod = readMethod
34
34
  this.maxConcurrentDeviceRead = maxConcurrentDeviceRead
35
35
  this.maxConcurrentSinglePointRead = maxConcurrentSinglePointRead
36
+ this.concurrentTaskDelay = concurrentTaskDelay
36
37
  this.name = name
37
38
  }
38
39
 
@@ -219,7 +220,8 @@ module.exports = {
219
220
  id: k,
220
221
  task: async () => {
221
222
  return await smartReadProperty(
222
- this.client, v.device, v.points, this.readMethod, this.maxConcurrentSinglePointRead
223
+ this.client, v.device, v.points, this.readMethod,
224
+ this.maxConcurrentSinglePointRead, 5, this.concurrentTaskDelay
223
225
  );
224
226
  }
225
227
  }));
@@ -25,6 +25,7 @@ module.exports = {
25
25
  constructor(
26
26
  client, eventEmitter, devices, points, writePoints,
27
27
  maxConcurrentDeviceWrite = 2, maxConcurrentPointWrite = 1,
28
+ concurrentTaskDelay = 50,
28
29
  name = 'write point'
29
30
  ) {
30
31
  super();
@@ -35,6 +36,7 @@ module.exports = {
35
36
  this.writePoints = writePoints
36
37
  this.maxConcurrentDeviceWrite = maxConcurrentDeviceWrite
37
38
  this.maxConcurrentPointWrite = maxConcurrentPointWrite
39
+ this.concurrentTaskDelay = concurrentTaskDelay
38
40
  this.name = name
39
41
  }
40
42
 
@@ -277,7 +279,7 @@ module.exports = {
277
279
  task: async () => {
278
280
  return await smartWriteProperty(
279
281
  this.client, v.device, v.writePoints, smartWriteEvent,
280
- this.maxConcurrentPointWrite
282
+ this.maxConcurrentPointWrite, this.concurrentTaskDelay
281
283
  );
282
284
  }
283
285
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@halsystems/red-bacnet",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "NodeRED BACnet IP client",
5
5
  "email": "open_source@halsystems.com.au",
6
6
  "repository": {