diff --git a/docs/usermanual.md b/docs/usermanual.md index bd8c1f163..04e73a551 100644 --- a/docs/usermanual.md +++ b/docs/usermanual.md @@ -243,7 +243,11 @@ Example of these `ngsild` payloads are the following ones: } ``` -Note that array of entities are handled as a multiple measure, each entity is a measure. +Some additional considerations to take into account: + +- In the case of array of entities, they are handled as a multiple measure, i.e. each entity is a measure. +- The `type` of the attribute is the one used in the provision of the attribute, not the one in the measure. The exception is the autoprovisioned devices case, in which case the `type` of the attribute is taken from the measure (given the attribute lacks proviosioned type). In this latter case, if the attribute `type` is not included in the measure the [explicit type omission rules for Context Broker](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/orion-api.md#partial-representations) are also taken into account in this case. +- In the case of NGSI-LD, fields different from `type`, `value` or `object` (e.g. `observedAt` in the examples above) are include as NGSI-v2 metadata in the entity corresponding to the measure at Context Broker. Note IOTA doesn't provide the `type` for that metadata, so the Context Broker applies [a default type based in the metadata `value` JSON type](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/orion-api.md#partial-representations). ##### SOAP-XML Measure reporting diff --git a/lib/commonBindings.js b/lib/commonBindings.js index ef82d46ca..2a7eca50f 100644 --- a/lib/commonBindings.js +++ b/lib/commonBindings.js @@ -73,11 +73,12 @@ function parseMessage(message) { * Find the attribute given by its name between all the active attributes of the given device, returning its type, or * null otherwise. * - * @param {String} attribute Name of the attribute to find. - * @param {Object} device Device object containing all the information about a device. + * @param {String} attribute Name of the attribute to find. + * @param {Object} device Device object containing all the information about a device. + * @param {measureType} type Type of measure attribute according with measure when available (ngsiv2 and ngsild measures) * @return {String} String identifier of the attribute type. */ -function guessType(attribute, device) { +function guessType(attribute, device, measureType) { if (device.active) { for (let i = 0; i < device.active.length; i++) { if (device.active[i].name === attribute) { @@ -89,7 +90,11 @@ function guessType(attribute, device) { if (attribute === constants.TIMESTAMP_ATTRIBUTE) { return constants.TIMESTAMP_TYPE_NGSI2; } - return constants.DEFAULT_ATTRIBUTE_TYPE; + if (measureType) { + return measureType; + } else { + return constants.DEFAULT_ATTRIBUTE_TYPE; + } } function extractAttributes(device, current, payloadType) { @@ -113,7 +118,7 @@ function extractAttributes(device, current, payloadType) { if (payloadType.toLowerCase() === constants.PAYLOAD_NGSIv2) { valuesEntity.push({ name: k, - type: entity[k].type, + type: guessType(k, device, entity[k].type), value: entity[k].value, metadata: entity[k].metadata ? entity[k].metadata : undefined }); @@ -126,13 +131,22 @@ function extractAttributes(device, current, payloadType) { ent.value = entity[k]; } else { if (entity[k].type) { - ent.type = entity[k].type; + ent.type = guessType(k, device, entity[k].type); if (['property', 'geoproperty'].includes(entity[k].type.toLowerCase())) { ent.value = entity[k].value; } else if (entity[k].type.toLowerCase() === 'relationship') { ent.value = entity[k].object; } } + // Add other stuff as metadata + for (let key in entity[k]) { + if (!['type', 'value', 'object'].includes(key.toLowerCase())) { + if (!ent.metadata) { + ent.metadata = {}; + } + ent.metadata[key] = { "value": entity[k][key] }; + } + } } valuesEntity.push(ent); } @@ -149,7 +163,7 @@ function extractAttributes(device, current, payloadType) { if (current.hasOwnProperty(k)) { values.push({ name: k, - type: guessType(k, device), + type: guessType(k, device, null), value: current[k] }); } @@ -218,7 +232,7 @@ function singleMeasure(apiKey, deviceId, attribute, device, parsedMessage) { const values = [ { name: attribute, - type: guessType(attribute, device), + type: guessType(attribute, device, null), value: parsedMessage[0] } ]; diff --git a/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure.json b/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure.json index 214b4ab87..a2da1a2ff 100644 --- a/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure.json +++ b/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure.json @@ -3,7 +3,12 @@ "type": "AnMQTTDevice", "status": { "type": "Property", - "value": "free" + "value": "free", + "metadata": { + "observedAt":{ + "value": "2018-09-21T12:00:00Z" + } + } }, "category": { "type": "Property", diff --git a/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure2.json b/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure2.json index 36ca7c47f..3428dd809 100644 --- a/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure2.json +++ b/test/unit/ngsiv2/contextRequests/ngsildPayloadMeasure2.json @@ -3,7 +3,12 @@ "type": "AnMQTTDevice", "status": { "type": "Property", - "value": "free" + "value": "free", + "metadata": { + "observedAt": { + "value": "2012-09-21T12:00:00Z" + } + } }, "category": { "type": "Property",