Skip to content

Commit

Permalink
Merge a101427 into c460e64
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroVega committed Apr 4, 2024
2 parents c460e64 + a101427 commit ba48346
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 9 deletions.
6 changes: 3 additions & 3 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ parameters. The specific parameters that can be configured for a given config gr
### Devices

A device contains the information that connects a physical device to a particular entity in the Context Broker. Devices
are identified by a `device_id`, and they are associated to an existing config group based in `apiKey` matching or
`type` matching (in the case `apiKey` matching fails). For instance, let's consider a situation in which a config group
has been provisioned with `type=X`/`apiKey=111` and no other config group has been provisioned.
are identified by a `device_id`, and they are associated to an existing config group based in `apiKey` matching. For
instance, let's consider a situation in which a config group has been provisioned with `type=X`/`apiKey=111` and no
other config group has been provisioned.

The IoT Agents offer a provisioning API where devices can be preregistered, so all the information about service and
subservice mapping, security information and attribute configuration can be specified in a per device way instead of
Expand Down
20 changes: 15 additions & 5 deletions lib/services/ngsi/entities-NGSI-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
let jexlctxt = {}; //will store the whole context (not just for JEXL)
let payload = {}; //will store the final payload
let timestamp = { type: constants.TIMESTAMP_TYPE_NGSI2 }; //timestamp scafold-attr for insertions.
let timestampAttr = null;
let plainMeasures = null; //will contain measures POJO
let idTypeSSSList = pluginUtils.getIdTypeServSubServiceFromDevice(typeInformation);

Expand Down Expand Up @@ -308,15 +309,14 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
jexlctxt = reduceAttrToPlainObject(idTypeSSSList, jexlctxt);

//Managing timestamp (mustInsertTimeInstant flag to decide if we should insert Timestamp later on)
const mustInsertTimeInstant =
typeInformation.timestamp !== undefined
? typeInformation.timestamp
: false;
const mustInsertTimeInstant = typeInformation.timestamp !== undefined ? typeInformation.timestamp : false;

if (mustInsertTimeInstant) {
//remove TimeInstant from measures
measures = measures.filter((item) => item.name !== constants.TIMESTAMP_ATTRIBUTE);

if (typeInformation && typeInformation.active) {
timestampAttr = typeInformation.active.filter((item) => item.name === constants.TIMESTAMP_ATTRIBUTE);
}
if (plainMeasures[constants.TIMESTAMP_ATTRIBUTE]) {
//if it comes from a measure
if (moment(plainMeasures[constants.TIMESTAMP_ATTRIBUTE], moment.ISO_8601, true).isValid()) {
Expand All @@ -327,6 +327,16 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
);
return;
}
} else if (timestampAttr && timestampAttr.length > 0 && plainMeasures[timestampAttr[0]['object_id']]) {
// Maybe TimeInstant is a mapped attribute
if (moment(plainMeasures[timestampAttr[0]['object_id']], moment.ISO_8601, true).isValid()) {
timestamp.value = plainMeasures[timestampAttr[0]['object_id']];
} else {
callback(
new errors.BadTimestamp(plainMeasures[timestampAttr[0]['object_id']], entityName, typeInformation)
);
return;
}
} else if (!typeInformation.timezone) {
timestamp.value = new Date().toISOString();
jexlctxt[constants.TIMESTAMP_ATTRIBUTE] = timestamp.value;
Expand Down
94 changes: 93 additions & 1 deletion test/functional/testCases.js
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,8 @@ const testCases = [
]
},
{
describeName: '0140 - Simple group with active attribute + chained JEXL expression text (a | trim | replacestr("hello","hi"))',
describeName:
'0140 - Simple group with active attribute + chained JEXL expression text (a | trim | replacestr("hello","hi"))',
provision: {
url: 'http://localhost:' + config.iota.server.port + '/iot/services',
method: 'POST',
Expand Down Expand Up @@ -1976,6 +1977,97 @@ const testCases = [
}
]
},
{
describeName: '0430 - Simple group with active attribute + timestamp mapping defined',
provision: {
url: 'http://localhost:' + config.iota.server.port + '/iot/services',
method: 'POST',
json: {
services: [
{
resource: '/iot/json',
apikey: globalEnv.apikey,
timestamp: true,
entity_type: globalEnv.entity_type,
commands: [],
lazy: [],
attributes: [
{
object_id: 'mydatetime',
name: 'TimeInstant',
type: 'DateTime'
}
]
}
]
},
headers: {
'fiware-service': globalEnv.service,
'fiware-servicepath': globalEnv.servicePath
}
},
should: [
{
shouldName:
'A - WHEN sending a measure through http IT should map the measure to timestamp attribute and use it for timestmap sent to Context Broker',
type: 'single',
measure: {
url: 'http://localhost:' + config.http.port + '/iot/json',
method: 'POST',
qs: {
i: globalEnv.deviceId,
k: globalEnv.apikey
},
json: {
mydatetime: '2022-02-02T02:22:22.222Z'
}
},
expectation: {
id: globalEnv.entity_name,
type: globalEnv.entity_type,
TimeInstant: {
value: '2022-02-02T02:22:22.222Z',
type: 'DateTime'
}
}
},
{
shouldName:
'A - WHEN sending a measure through http IT should map the measure to timestamp attribute and use it for timestmap and other metadata attributes sent to Context Broker',
type: 'single',
measure: {
url: 'http://localhost:' + config.http.port + '/iot/json',
method: 'POST',
qs: {
i: globalEnv.deviceId,
k: globalEnv.apikey
},
json: {
mydatetime: '2022-02-02T02:22:22.222Z',
a: 23
}
},
expectation: {
id: globalEnv.entity_name,
type: globalEnv.entity_type,
a: {
value: 23,
type: 'Text',
metadata: {
TimeInstant: {
value: '2022-02-02T02:22:22.222Z',
type: 'DateTime'
}
}
},
TimeInstant: {
value: '2022-02-02T02:22:22.222Z',
type: 'DateTime'
}
}
}
]
},
// 0500 - EXPLICIT ATTRIBUTES TESTS
{
describeName: '0500 - Group with explicit attrs:false (boolean) + active atributes',
Expand Down

0 comments on commit ba48346

Please sign in to comment.