Skip to content

Commit

Permalink
Merge branch 'master' into task/update_handler_with_old_device
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroVega authored Jun 4, 2024
2 parents 67a1b7a + a8a0791 commit 90ae36f
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 123 deletions.
3 changes: 2 additions & 1 deletion CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Fix: update device using previous device apikey to avoid error when apikey is updated /(iota-json#833)
- Fix: default express limit to 1Mb instead default 100Kb and allow change it throught a conf env var 'IOTA_EXPRESS_LIMIT' (iota-json#827)
- Fix: allow send multiple measures to CB in a batch (POST /v2/op/update) and sorted by TimeInstant when possible, instead of using multiples single request (iotagent-json#825, iotagent-node-lib#1612)
- Fix: default express limit to 1Mb instead default 100Kb and allow change it throught a conf env var 'IOTA_EXPRESS_LIMIT' (iota-json#827)
5 changes: 2 additions & 3 deletions docs/usermanual.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ t|15|k|abc
In this example, two attributes, one named "t" with value "15" and another named "k" with value "abc" are transmitted.
Values in Ultralight 2.0 are not typed (everything is treated as a string).

Multiple groups of measures can be combined into a single request, using the `#` character. In that case, a different
Multiple groups of measures can be combined into a single request (but just for HTTP/POST or MQTT), using the `#` character. In that case, a different
NGSI request will be generated for each group of measures. E.g.:

```text
gps|1.2/3.4#t|10
```

This will generate two NGSI requests for the same entity, one for each one of the values. Each one of those requests can
contain any number of attributes.
This will generate two elements in the NGSI batch update request (POST /v2/op/update) for the same entity, one for each one of the measures. Each one of those elements can contain any number of attributes.

Measure groups can additionally have an optional timestamp, with the following syntax:

Expand Down
6 changes: 3 additions & 3 deletions lib/bindings/HTTPBindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function returnCommands(req, res, next) {
}

function handleIncomingMeasure(req, res, next) {
let updates = [];
let update = [];
context = fillService(context, { service: 'n/a', subservice: 'n/a' });
// prettier-ignore
config.getLogger().debug(context, 'Processing multiple HTTP measures for device %s with apiKey %j',
Expand All @@ -223,10 +223,10 @@ function handleIncomingMeasure(req, res, next) {
function processHTTPWithDevice(device) {
context = fillService(context, device);
if (req.ulPayload) {
updates = req.ulPayload.reduce(commonBindings.processMeasureGroup.bind(null, device, req.apiKey), []);
update = [req.ulPayload].reduce(commonBindings.processMeasureGroup.bind(null, device, req.apiKey), []);
}

async.series(updates, function (error) {
async.series(update, function (error) {
if (error) {
next(error);
// prettier-ignore
Expand Down
35 changes: 19 additions & 16 deletions lib/commonBindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,32 +128,35 @@ function manageConfigurationRequest(apiKey, deviceId, device, objMessage) {

/* eslint-disable-next-line no-unused-vars */
function processMeasureGroup(device, apikey, previous, current, index) {
const values = [];
if (current.command) {
if (current[0] && current[0].command) {
previous.push(
iotAgentLib.setCommandResult.bind(
null,
device.name,
config.getConfig().iota.defaultResource,
apikey,
current.command,
current.value,
current[0].command,
current[0].value,
constants.COMMAND_STATUS_COMPLETED,
device
)
);
} else {
for (const k in current) {
if (current.hasOwnProperty(k)) {
values.push({
name: k,
type: guessType(k, device),
value: current[k]
});
const val = [];
for (let curr of current) {
const values = [];
for (const k in curr) {
if (curr.hasOwnProperty(k)) {
values.push({
name: k,
type: guessType(k, device),
value: curr[k]
});
}
}
val.push(values);
}

previous.push(iotAgentLib.update.bind(null, device.name, device.type, '', values, device));
previous.push(iotAgentLib.update.bind(null, device.name, device.type, '', val, device));
}

return previous;
Expand All @@ -168,7 +171,7 @@ function processMeasureGroup(device, apikey, previous, current, index) {
* @param {String} messageStr UL payload parsed to string.
*/
function multipleMeasures(apiKey, device, messageStr) {
let updates = [];
let update = [];
let parsedMessage;
context = fillService(context, device);
config.getLogger().debug(context, 'Processing multiple measures for device %s with apiKey %s', device.id, apiKey);
Expand All @@ -181,9 +184,9 @@ function multipleMeasures(apiKey, device, messageStr) {
return;
}
config.getLogger().debug(context, 'stringMessage: %s parsedMessage: %s', messageStr, parsedMessage);
updates = parsedMessage.reduce(processMeasureGroup.bind(null, device, apiKey), []);
update = [parsedMessage].reduce(processMeasureGroup.bind(null, device, apiKey), []);

async.series(updates, function (error) {
async.series(update, function (error) {
if (error) {
config.getLogger().error(
context,
Expand Down
28 changes: 2 additions & 26 deletions test/unit/ngsiv2/amqpBinding-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,7 @@ describe('AMQP Transport binding: measures', function () {
contextBrokerMock
.matchHeader('fiware-service', 'smartgondor')
.matchHeader('fiware-servicepath', '/gardens')
.post(
'/v2/entities?options=upsert',
utils.readExampleFile('./test/unit/ngsiv2/contextRequests/singleMeasure.json')
)
.reply(204);

contextBrokerMock
.matchHeader('fiware-service', 'smartgondor')
.matchHeader('fiware-servicepath', '/gardens')
.post(
'/v2/entities?options=upsert',
utils.readExampleFile('./test/unit/ngsiv2/contextRequests/secondSingleMeasure.json')
)
.post('/v2/op/update', utils.readExampleFile('./test/unit/ngsiv2/contextRequests/multimeasure.json'))
.reply(204);
});

Expand All @@ -248,19 +236,7 @@ describe('AMQP Transport binding: measures', function () {
contextBrokerMock
.matchHeader('fiware-service', 'smartgondor')
.matchHeader('fiware-servicepath', '/gardens')
.post(
'/v2/entities?options=upsert',
utils.readExampleFile('./test/unit/ngsiv2/contextRequests/multipleMeasure.json')
)
.reply(204);

contextBrokerMock
.matchHeader('fiware-service', 'smartgondor')
.matchHeader('fiware-servicepath', '/gardens')
.post(
'/v2/entities?options=upsert',
utils.readExampleFile('./test/unit/ngsiv2/contextRequests/secondMultipleMeasure.json')
)
.post('/v2/op/update', utils.readExampleFile('./test/unit/ngsiv2/contextRequests/multimeasure2.json'))
.reply(204);
});

Expand Down
21 changes: 21 additions & 0 deletions test/unit/ngsiv2/contextRequests/multimeasure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"actionType": "append",
"entities": [
{
"id": "Second UL Device",
"type": "AnMQTTDevice",
"temperature": {
"type": "celsius",
"value": 23
}
},
{
"id": "Second UL Device",
"type": "AnMQTTDevice",
"humidity": {
"type": "degrees",
"value": 98
}
}
]
}
29 changes: 29 additions & 0 deletions test/unit/ngsiv2/contextRequests/multimeasure2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"actionType": "append",
"entities": [
{
"id": "Second UL Device",
"type": "AnMQTTDevice",
"temperature": {
"type": "celsius",
"value": 23
},
"humidity": {
"type": "degrees",
"value": 98
}
},
{
"id": "Second UL Device",
"type": "AnMQTTDevice",
"temperature": {
"type": "celsius",
"value": 16
},
"humidity": {
"type": "degrees",
"value": 34
}
}
]
}
Loading

0 comments on commit 90ae36f

Please sign in to comment.