iotagent-node-lib 2.22.0 → 2.23.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.
@@ -314,13 +314,52 @@ function sendQueryValueNgsi2(entityName, attributes, typeInformation, token, cal
314
314
  );
315
315
  }
316
316
 
317
+ function extractContextFromPayload(payload) {
318
+ //{b: {value: 3,type: "string"},c: {value: false,type: "string"},d:{value: {g: 45},type: "string"},id: "tamcaysanto",type: "WaterTankMulti"}
319
+ //to
320
+ //{b:3,c:false,d:{g:45}}
321
+
322
+ let ctx = {};
323
+ for (const key in payload) {
324
+ if (key !== 'type' && key !== 'id') {
325
+ ctx[key] = payload[key].value;
326
+ }
327
+ }
328
+ return ctx;
329
+ }
317
330
  /**
318
331
  * Remove id, type and any hidden attrs after processing
319
332
  *
320
333
  * @param {Object} enities Unprocessed entities
321
334
  * @param {Object} typeInformation Configuration information for the device.
322
335
  */
323
- function removeHiddenAttrsFromMultiEntity(entities, typeInformation) {
336
+ function removeHiddenAttrsFromMultiEntity(entities, typeInformation, payload) {
337
+ function filterForEntity(entity, explicitAttrsList, typeInformation) {
338
+ let effectiveList = [];
339
+ for (const attr of explicitAttrsList) {
340
+ if (typeof attr === 'string') {
341
+ effectiveList.push(attr);
342
+ } else if (typeof attr === 'object' && attr.object_id) {
343
+ //find objectId in active attributes
344
+ for (const active of typeInformation.active) {
345
+ if (active.object_id === attr.object_id) {
346
+ if (
347
+ active &&
348
+ active.name &&
349
+ active.entity_name &&
350
+ active.entity_name === entity.id
351
+ //if name is an expression it could fail... BUT IT WORKS!
352
+ ) {
353
+ effectiveList.push(active.name);
354
+ }
355
+ continue; //object_id must be unique
356
+ }
357
+ }
358
+ }
359
+ }
360
+ return effectiveList;
361
+ }
362
+
324
363
  let explicitAttrsList;
325
364
  if (typeInformation.explicitAttrs) {
326
365
  explicitAttrsList = [];
@@ -344,7 +383,10 @@ function removeHiddenAttrsFromMultiEntity(entities, typeInformation) {
344
383
  } else if (typeof typeInformation.explicitAttrs === 'string') {
345
384
  entities.forEach((entity) => {
346
385
  const attsArray = pluginUtils.extractAttributesArrayFromNgsi2Entity(entity);
347
- const ctx = jexlParser.extractContext(attsArray);
386
+ const ctx = {
387
+ ...jexlParser.extractContext(attsArray),
388
+ ...extractContextFromPayload(payload)
389
+ }; //maybe overlapping between this two objects.
348
390
  const res = jexlParser.applyExpression(typeInformation.explicitAttrs, ctx, typeInformation);
349
391
  explicitAttrsList = explicitAttrsList.concat(res);
350
392
  });
@@ -352,7 +394,10 @@ function removeHiddenAttrsFromMultiEntity(entities, typeInformation) {
352
394
  }
353
395
  if (explicitAttrsList && explicitAttrsList.length >= 0) {
354
396
  entities.forEach((entity) => {
355
- const hidden = _.difference(_.keys(entity), explicitAttrsList);
397
+ //some attrs are object_ids {object_id:oid} and need to be resolved for this entity
398
+ //"explicitAttrs" : "attrA?['attrA',{object_id:'foo'}]:['attrB',{object_id:'bar'}]",
399
+ let efectiveAttrsList = filterForEntity(entity, explicitAttrsList, typeInformation);
400
+ const hidden = _.difference(_.keys(entity), efectiveAttrsList);
356
401
  logger.debug(context, 'removeHiddenAttrsFromMultiEntity %s from entity %s', hidden, entity);
357
402
  hidden.forEach((attr) => {
358
403
  delete entity[attr];
@@ -361,13 +406,14 @@ function removeHiddenAttrsFromMultiEntity(entities, typeInformation) {
361
406
  }
362
407
  return entities;
363
408
  }
409
+
364
410
  /**
365
411
  * Remove id, type and any hidden attrs after processing
366
412
  *
367
413
  * @param {Object} result An Unprocessed entity
368
414
  * @param {Object} typeInformation Configuration information for the device.
369
415
  */
370
- function removeHiddenAttrs(result, typeInformation) {
416
+ function removeHiddenAttrs(result, typeInformation, payload) {
371
417
  delete result.id;
372
418
  delete result.type;
373
419
  let explicitAttrsList;
@@ -388,7 +434,10 @@ function removeHiddenAttrs(result, typeInformation) {
388
434
  }
389
435
  } else if (typeInformation.explicitAttrs && typeof typeInformation.explicitAttrs === 'string') {
390
436
  const attsArray = pluginUtils.extractAttributesArrayFromNgsi2Entity(result);
391
- const ctx = jexlParser.extractContext(attsArray);
437
+ const ctx = {
438
+ ...jexlParser.extractContext(attsArray),
439
+ ...extractContextFromPayload(payload)
440
+ }; //maybe overlapping between this two objects. Measures not in active attrs.
392
441
  const res = jexlParser.applyExpression(typeInformation.explicitAttrs, ctx, typeInformation);
393
442
  explicitAttrsList = res;
394
443
  }
@@ -481,7 +530,7 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
481
530
  }
482
531
  options.json = {
483
532
  actionType: 'append',
484
- entities: removeHiddenAttrsFromMultiEntity(result, typeInformation)
533
+ entities: removeHiddenAttrsFromMultiEntity(result, typeInformation, payload)
485
534
  };
486
535
  if (config.getConfig().appendMode === true) {
487
536
  options.json.actionType = 'append';
@@ -489,7 +538,7 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
489
538
  options.json.actionType = 'update';
490
539
  }
491
540
  } else {
492
- options.json = removeHiddenAttrs(result, typeInformation);
541
+ options.json = removeHiddenAttrs(result, typeInformation, payload);
493
542
  logger.debug(context, 'typeInformation: %j', typeInformation);
494
543
  if (
495
544
  'timestamp' in typeInformation && typeInformation.timestamp !== undefined
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "iotagent-node-lib",
3
3
  "license": "AGPL-3.0-only",
4
4
  "description": "IoT Agent library to interface with NGSI Context Broker",
5
- "version": "2.22.0",
5
+ "version": "2.23.0",
6
6
  "homepage": "https://github.com/telefonicaid/iotagent-node-lib",
7
7
  "keywords": [
8
8
  "fiware",
@@ -1 +1,12 @@
1
- {"myattr":{"type": "String","value": "location"}}
1
+ {
2
+ "mylocation": {
3
+ "type": "geo:json",
4
+ "value": {
5
+ "coordinates": [
6
+ 13,
7
+ 52
8
+ ],
9
+ "type": "Point"
10
+ }
11
+ }
12
+ }
@@ -271,7 +271,7 @@ const iotAgentConfig = {
271
271
  expression: "{coordinates: [lon,lat], type: 'Point'}"
272
272
  }
273
273
  ],
274
- explicitAttrs: '[ "location" ]'
274
+ explicitAttrs: ' location&&price ? [ "location", "price" ] : location ? [ "location" ] : []'
275
275
  },
276
276
  GPS4: {
277
277
  commands: [],
@@ -314,12 +314,14 @@ const iotAgentConfig = {
314
314
  type: 'number'
315
315
  },
316
316
  {
317
- name: 'location',
318
- type: 'geo:json',
319
- expression: "{coordinates: [lon,lat], type: 'Point'}"
317
+ object_id: 'theLocation',
318
+ name: 'mylocation',
319
+ type: 'geo:json'
320
320
  }
321
321
  ],
322
- explicitAttrs: "[ 'myattr' ]"
322
+ explicitAttrs: "theLocation ? ['mylocation'] : []"
323
+ // #1267 this is not working:
324
+ //explicitAttrs: "theLocation ? [{object_id: 'theLocation'}] : []"
323
325
  },
324
326
  GPS6: {
325
327
  commands: [],
@@ -1184,9 +1186,9 @@ describe('Java expression language (JEXL) based transformations plugin', functio
1184
1186
  value: 13
1185
1187
  },
1186
1188
  {
1187
- name: 'myattr',
1188
- type: 'String',
1189
- value: 'location'
1189
+ name: 'theLocation',
1190
+ type: 'geo:json',
1191
+ value: { coordinates: [13, 52], type: 'Point' }
1190
1192
  },
1191
1193
  {
1192
1194
  name: 'TimeInstant',