Commands in IotAgent Ultralight 2.0 FIWARE - fiware

I am trying to send a command to a device using Orion + Ultralight 2.0.
The device is registered and I can send measures easily. I want to work in the pooling mode in order to execute commands, but when I execute the updateContext operation, IDAS doesn't found the entity. Here are the configuration and the logs:
Configuration:
var config = {};
config.mqtt = {
host: 'mosquitto',
port: 1883
};
config.http = {
port: 7896
};
config.iota = {
logLevel: 'DEBUG',
timestamp: true,
contextBroker: {
host: 'MY_IP',
port: '1026'
},
server: {
port: 4041
},
deviceRegistry: {
type: 'mongodb'
},
mongodb: {
host: 'mongo',
port: '27017',
db: 'iotagentul'
},
types: {},
service: 'howtoService',
subservice: '/howto',
providerUrl: 'http://YIP:4041',
deviceRegistrationDuration: 'P1M',
defaultType: 'Thing'
};
config.defaultKey = 'TEF';
module.exports = config;
I have tried different IP's and routes, and at the end i tried with the public IP, assuring that there is communication from the outside to those ports.
Device registration:
curl -X POST \
http://MYIP:4041/iot/devices \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-d '{
"devices": [{
"device_id": "muvone",
"protocol": "IoTA-UL",
"entity_name": "muvone",
"entity_type": "Thing",
"attributes": [{
"object_id": "t",
"name": "temperature",
"type": "Float"
}],
"commands": [{
"name":"blink",
"type": "command",
"value": "muvone#blink|%s"
}],
"static_attributes": []
}]
}'
Then I send some observations from a physical device and from POSTMAN:
curl -X POST \
'http://MYIP:7896/iot/d?i=muvone&k=TEF&getCmd=1' \
-H 'cache-control: no-cache' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-d 'temperature|16'
Which actually updates the entity correctly, as can be seen in Orion Context Broker:
Query:
curl -X GET \
http://MYIP:1026/v2/entities \
-H 'cache-control: no-cache' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
Response:
[
{
"id": "muvone",
"type": "Thing",
"TimeInstant": {
"type": "ISO8601",
"value": "2017-06-01T11:37:52.537Z",
"metadata": {}
},
"blink_info": {
"type": "commandResult",
"value": " ",
"metadata": {}
},
"blink_status": {
"type": "commandStatus",
"value": "UNKNOWN",
"metadata": {}
},
"temperature": {
"type": "Float",
"value": "16",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2017-06-01T11:37:52.537Z"
}
}
}
}
]
So now, If I want to send a command, I have done it in a lot of ways. I tried following this guide:
http://fiware-iot-stack.readthedocs.io/en/master/topics/device_connection/index.html
So I tried to use the following request:
curl -X PUT \
http://MYIP:1026/v2/entities \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-d '{
"id": "muvone",
"type": "Thing",
"blink": {
"type" : "command",
"value" : "true"
}
}'
Which response is:
{
"error": "MethodNotAllowed",
"description": "method not allowed"
}
So I tried updating a single attribute, in this case the blink attribute, which is a command. This should trigger that the Orion Context Broker acts as a NGSI proxy and passes the request to the IoTAgent, which occurs. But the problem is that the IoTAgent doesn't find the entity, as it can be seen in the logs:
curl -X PUT \
'http://MYIP:1026/v2/entities/muvone/attrs/blink?type=Thing' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-d '{
"type": "command",
"value": "true"
}'
or
curl -X PUT \
'http://MYIP:1026/v2/entities/muvone/attrs/blink?type=Thing' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-H 'postman-token: 6b42d06d-2a9f-3081-e315-bd9919aeded5' \
-d '{
"value": "true"
}'
Responds with:
{
"error": "NotFound",
"description": "The requested entity has not been found. Check type and id"
}
Edit: The get v2/entities to orion result, after issuing these requests is:
[
{
"id": "muvone",
"type": "Thing",
"TimeInstant": {
"type": "ISO8601",
"value": "2017-06-02T10:26:32.212Z",
"metadata": {}
},
"blink_info": {
"type": "commandResult",
"value": " ",
"metadata": {}
},
"blink_status": {
"type": "commandStatus",
"value": "UNKNOWN",
"metadata": {}
},
"temperature": {
"type": "Float",
"value": "26",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2017-06-02T10:26:32.212Z"
}
}
}
}
]
Now, having a look at Orion and IoTAgent logs, it can be seen that IoTAgent doesn't find the entity:
Orion logs to the request:
time=Thursday 01 Jun 12:10:13 2017.880Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000039 | from=pending | srv=pending | subsrv=pending | comp=Orion | op=logMsg.h[1832]:lmTransactionStart | msg=Starting transaction from 91.126.73.210:2880/v2/entities/muvone/attrs/blink
time=Thursday 01 Jun 12:10:13 2017.880Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000039 | from=91.126.73.210 | srv=pending | subsrv=/howto | comp=Orion | op=rest.cpp[872]:servicePathSplit | msg=Service Path 0: '/howto'
time=Thursday 01 Jun 12:10:13 2017.881Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000039 | from=91.126.73.210 | srv=howtoservice | subsrv=/howto | comp=Orion | op=connectionOperations.cpp[237]:collectionCount | msg=Database Operation Successful (count: { _id.id: "muvone", _id.type: "Thing", _id.servicePath: { $in: [ /^/howto$/ ] } })
time=Thursday 01 Jun 12:10:13 2017.881Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000039 | from=91.126.73.210 | srv=howtoservice | subsrv=/howto | comp=Orion | op=connectionOperations.cpp[92]:collectionQuery | msg=Database Operation Successful (query: { _id.id: "muvone", _id.type: "Thing", _id.servicePath: { $in: [ /^/howto$/ ] } })
time=Thursday 01 Jun 12:10:13 2017.881Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000039 | from=91.126.73.210 | srv=howtoservice | subsrv=/howto | comp=Orion | op=connectionOperations.cpp[175]:collectionRangedQuery | msg=Database Operation Successful (query: { query: { $or: [ { contextRegistration.entities: { $in: [ { id: "muvone", type: "Thing" }, { type: "Thing", id: "muvone" } ] } }, { contextRegistration.entities.id: { $in: [] } } ], expiration: { $gt: 1496319013 }, contextRegistration.attrs.name: { $in: [ "blink" ] }, servicePath: { $in: [ /^/howto$/ ] } }, orderby: { _id: 1 } })
time=Thursday 01 Jun 12:10:13 2017.882Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000040 | from=pending | srv=pending | subsrv=pending | comp=Orion | op=logMsg.h[1832]:lmTransactionStart | msg=Starting transaction to http://MYIP:4041//updateContext
time=Thursday 01 Jun 12:10:13 2017.882Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000040 | from=pending | srv=pending | subsrv=pending | comp=Orion | op=httpRequestSend.cpp[577]:httpRequestSendWithCurl | msg=Sending message 14 to HTTP server: sending message of 558 bytes to HTTP server
time=Thursday 01 Jun 12:10:13 2017.886Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000040 | from=pending | srv=pending | subsrv=pending | comp=Orion | op=httpRequestSend.cpp[598]:httpRequestSendWithCurl | msg=Notification Successfully Sent to http://MYIP:4041//updateContext
time=Thursday 01 Jun 12:10:13 2017.886Z | lvl=INFO | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=1496315963-946-00000000040 | from=pending | srv=pending | subsrv=pending | comp=Orion | op=logMsg.h[1916]:lmTransactionEnd | msg=Transaction ended
time=Thursday 01 Jun 12:10:13 2017.886Z | lvl=WARN | corr=N/A | trans=N/A | from=N/A | srv=N/A | subsrv=N/A | comp=Orion | op=postUpdateContext.cpp[225]:updateForward | msg=Internal Error (error parsing reply from prov app: )
time=Thursday 01 Jun 12:10:13 2017.886Z | lvl=INFO | corr=N/A | trans=N/A | from=N/A | srv=N/A | subsrv=N/A | comp=Orion | op=logMsg.h[1916]:lmTransactionEnd | msg=Transaction ended
IDAS log:
time=2017-06-01T12:10:13.882Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.GenericMiddlewares | srv=howtoservice | subsrv=/howto | msg=Request for path [//updateContext] from [MYIP:4041] | comp=IoTAgent
time=2017-06-01T12:10:13.882Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.GenericMiddlewares | srv=howtoservice | subsrv=/howto | msg=Body:
{
"contextElements": [
{
"type": "Thing",
"isPattern": "false",
"id": "muvone",
"attributes": [
{
"name": "blink",
"type": "command",
"value": "true"
}
]
}
],
"updateAction": "UPDATE"
}
| comp=IoTAgent
time=2017-06-01T12:10:13.883Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.ContextServer | srv=howtoservice | subsrv=/howto | msg=Handling update from [MYIP:4041] | comp=IoTAgent
time=2017-06-01T12:10:13.883Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.ContextServer | srv=howtoservice | subsrv=/howto | msg=[object Object] | comp=IoTAgent
time=2017-06-01T12:10:13.883Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.MongoDBDeviceRegister | srv=howtoservice | subsrv=/howto | msg=Looking for entity with name [muvone]. | comp=IoTAgent
time=2017-06-01T12:10:13.883Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.MongoDBDeviceRegister | srv=howtoservice | subsrv=/howto | msg=Entity [muvone] not found. | comp=IoTAgent
time=2017-06-01T12:10:13.884Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.ContextServer | srv=howtoservice | subsrv=/howto | msg=There was an error handling the update action: [object Object]. | comp=IoTAgent
time=2017-06-01T12:10:13.884Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.ContextServer | srv=howtoservice | subsrv=/howto | msg=Update error [ENTITY_NOT_FOUND] handing request: The entity with the requested id [muvone] was not found. | comp=IoTAgent
time=2017-06-01T12:10:13.884Z | lvl=DEBUG | corr=446f4532-46c3-11e7-b1a4-0242ac110003 | trans=8dcc19e7-e3ce-472a-a1bb-c7983dad7025 | op=IoTAgentNGSI.DomainControl | srv=howtoservice | subsrv=/howto | msg=response-time: 2 | comp=IoTAgent
In the mongo database, it can be seen that the registrations, entities and everything is set up correctly.
I have worked around this issue for days with no result.
Any help will be appreciated. Thanks in advance
UPDATE
After using the v1 of the Orion API, the result is the same that the given by v2:
curl -X POST \
http://MYIP:1026/v1/updateContext \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'fiware-service: howtoService' \
-H 'fiware-servicepath: /howto' \
-d '{
"contextElements": [
{
"type": "Thing",
"isPattern": "false",
"id": "muvone",
"attributes": [
{
"name": "blink",
"type": "command",
"value": "true"
}
]
}
],
"updateAction": "UPDATE"
} '
Result:
{
"errorCode": {
"code": "404",
"reasonPhrase": "No context element found"
}
}
2nd UPDATE
I have a service that sends the commands that I issue to the context broker. The difference is that if the command is defined in the device, it responses with the 404 error, but if it is not defined in the preprovision, it responds with the code 472:
Undefined command
curl -X POST \
http://localhost:3000/api/devices/1111/sendCommand/update_firmware \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"value":"example value"
}'
472:
{
"contextResponses": [
{
"contextElement": {
"type": "Thing",
"isPattern": "false",
"id": "muvone",
"attributes": [
{
"name": "update_firmware",
"type": "command",
"value": ""
}
]
},
"statusCode": {
"code": "472",
"reasonPhrase": "request parameter is invalid/not allowed",
"details": "action: UPDATE - entity: [muvone, Thing] - offending attribute: update_firmware"
}
}
]
}
Defined command:
curl -X POST \
http://localhost:3000/api/devices/1111/sendCommand/blink \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"value":"asd"
}'
404:
{
"errorCode": {
"code": "404",
"reasonPhrase": "No context element found"
}
}

I found the solution to this issue, and I think it must be considered as a bug. It was a problem with camelcases.
In my case, I was using the headers howtoService for the Fiware-service header, and in the database was stored correctly:
{ "_id" : ObjectId("5935316c4cfcb20001ec6181"), "polling" : true, "transport" : "HTTP", "protocol" : "IoTA-UL", "internalId" : null, "registrationId" : "5935316c5937ac933167d477", "subservice" : "/howto", "service" : "howtoService", "name" : "muvone", "type" : "Thing", "id" : "muvone", "creationDate" : ISODate("2017-06-05T10:24:44.336Z"), "subscriptions" : [ ], "staticAttributes" : [ ], "commands" : [ { "object_id" : "blink", "value" : "muvone#blink|%s", "type" : "command", "name" : "blink" } ], "active" : [ { "type" : "Float", "name" : "temperature", "object_id" : "ta" } ], "__v" : 0 }
But, when the operation from the IOTAgent comes, it uses lowercase, resulting in a Not found operation from mongo filters:
{ "op" : "query", "ns" : "iotagentul.devices", "query" : { "find" : "devices", "filter" : { "subservice" : "/howto", "service" : "howtoservice", "name" : "muvone" }, "projection" : { "__v" : 0 }, "limit" : 1, "batchSize" : 1, "singleBatch" : true }, "keysExamined" : 0, "docsExamined" : 1, "cursorExhausted" : true, "keyUpdates" : 0, "writeConflicts" : 0, "numYield" : 0, "locks" : { "Global" : { "acquireCount" : { "r" : NumberLong(2) } }, "Database" : { "acquireCount" : { "r" : NumberLong(1) } }, "Collection" : { "acquireCount" : { "r" : NumberLong(1) } } }, "nreturned" : 0, "responseLength" : 124, "protocol" : "op_query", "millis" : 0, "execStats" : { "stage" : "LIMIT", "nReturned" : 0, "executionTimeMillisEstimate" : 0, "works" : 3, "advanced" : 0, "needTime" : 2, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "limitAmount" : 1, "inputStage" : { "stage" : "PROJECTION", "nReturned" : 0, "executionTimeMillisEstimate" : 0, "works" : 3, "advanced" : 0, "needTime" : 2, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "transformBy" : { "__v" : 0 }, "inputStage" : { "stage" : "COLLSCAN", "filter" : { "$and" : [ { "name" : { "$eq" : "muvone" } }, { "service" : { "$eq" : "howtoservice" } }, { "subservice" : { "$eq" : "/howto" } } ] }, "nReturned" : 0, "executionTimeMillisEstimate" : 0, "works" : 3, "advanced" : 0, "needTime" : 2, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1 } } }, "ts" : ISODate("2017-06-05T10:40:37.401Z"), "client" : "172.17.0.4", "allUsers" : [ ], "user" : "" }
After updating in database the howtoService to howtoservice, the command works properly

Not sure what I'm going to say would solve your problem, but some things to take into account, after reading your question:
It is normal that PUT /v2/entities results in "Method not allowed". Take into account that according to the NGSIv2 specification, the /v2/entities URL only accept to verbs: GET (to retrieve a list of entities) and POST (to create new entities). This is not the way of updating existing entities.
Regarding the "Not found" error you get upon PUT /v2/entities/muvone/attrs/blink?type=Thing, please have a look to this issue report. According to that information, the command is progressed and, in fact, that is happening in your case (as the second line in the IOTA log shows).

Related

Error when invoke a PATCH command to Orion Context Broker

We're trying to invoke commands from Orion to IoT Device using PATCH and POST requests, but we're always having the following error:
Error [MANDATORY_PARAMS_NOT_FOUND] handing request:
Some of the mandatory params weren't found in the request: ["API Key","Device Id","Payload"]
Steps:
Create a "Device Entity" in Orion Context Broker
Provisioning a new Device
Create a Service in IoT JSON Agent
{
"services": [
{
"apikey": "my_api_key",
"protocol": [
"IoTA-JSON"
],
"cbroker": "orion:1026",
"entity_type": "Device",
"resource": "/iot/json"
}
]
}
Send a POST request to http://iot-agent-host:4041/v2/op/update to execute a command, via gateway, into the IoT Device (Works OK):
{
"actionType": "update",
"entities": [
{
"id": "shelly-1pm-test",
"type": "Device",
"cmd": {
"type": "command",
"value": {
"turn": "off",
"idDevice": "device001"
}
}
}
]
}
Send a PATCH request to http://context-broker-host:1026/v2/entities/entity-name/attrs to execute a command, via Orion CB, into the IoT Device, getting 204 in the response:
{
"cmd": {
"type": "command",
"value": {
"turn": "off",
"idDevice": "98cdac2e6101"
}
}
}
The command is not executed. Viewing the IoT JSON Agent logfile we can see:
[MANDATORY_PARAMS_NOT_FOUND] handing request: Some of the mandatory params weren't found in the request: ["API Key","Device Id","Payload"]
Any ideas?
Thanks in advance
MANDATORY_PARAMS_NOT_FOUND is an error message specific to the IoT Agent for JSON. It is usually invoked by an incoming measure which has failed to supply the necessary anti-spoofing information. It should not occur when a command is sent. You have not supplied the actuator provisioning call, but I assume it is something like this:
curl -L -X POST 'http://localhost:4041/iot/devices' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
--data-raw '{
"devices": [
{
"device_id": "bell001",
"entity_name": "urn:ngsi-ld:Bell:001",
"entity_type": "Bell",
"protocol": "PDI-IoTA-JSON",
"transport": "HTTP",
"endpoint": "http://my-device/iot/bell001",
"commands": [
{
"name": "ring",
"type": "command"
}
]
}
]
}'
Where http://my-device/iot/bell001 is the listening endpoint of the actuator. At a guess your device is responding to this by sending a response to http://iot-agent/iot/json - probably a GET - specifically a response without i or k or d parameters.
i: is the device ID.
k: the API Key for the device's service.
d: the data payload
If you set the IOTA_LOG_LEVEL=DEBUG, the following transactions should occur:
Incoming Request:
op=IoTAgentNGSI.ContextServer-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Handling v2 update from [iot-agent:4041] | comp=IoTAgent
op=IoTAgentNGSI.ContextServer-v2 | from=n/a | srv=openiot | subsrv=/ | msg={
"entities": [
{
"id": "Bell:001",
"type": "Bell",
"ring": {
"type": "command",
"value": "",
"metadata": {}
}
}
],
"actionType": "update"
} | comp=IoTAgent
Actuation Request:
op=IoTAgentNGSI.Request | from=n/a | srv=n/a | subsrv=n/a | msg=Options: {
"url": "http://iot-sensors:3001/iot/bell001",
"method": "POST",
"body": "{ring:''}",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/",
"content-type": "application/json"
},
"responseType": "text"
} | comp=IoTAgent
Set status to pending
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=n/a | subsrv=n/a | msg=Using the following NGSI v2 request:
{
"url": "http://orion:1026/v2/entities/Bell:001/attrs?type=Bell",
"method": "PATCH",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/"
},
"json": {
"ring_status": {
"type": "commandStatus",
"value": "PENDING",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.795Z"
}
}
}
}
If the device responds with 200, set status to OK
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Updating device value in the Context Broker at [http://orion:1026/v2/op/update] | comp=IoTAgent
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Using the following NGSI v2 request:
2022-07-12T06:47:59.944482296Z
{
"url": "http://orion:1026/v2/op/update",
"method": "POST",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/"
},
"json": {
"actionType": "update",
"entities": [
{
"ring_status": {
"type": "commandStatus",
"value": "OK",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.942Z"
}
}
},
"ring_info": {
"type": "commandResult",
"value": " ring OK",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.942Z"
}
}
}
]
}
}
I'm guessing that your device is responding incorrectly to the actuation request (number 2 in the list)

parsing jq returns null

I have a json output
{
"7": [
{
"devices": [
"/dev/sde"
],
"name": "osd-block-dcc9b386-529c-451e-9d84-8ccc4091102b",
"tags": {
"ceph.crush_device_class": "None",
"ceph.db_device": "/dev/nvme0n1p5",
"ceph.wal_device": "/dev/nvme0n1p6",
},
"type": "block",
"vg_name": "ceph-c4de9e90-853e-4569-b04f-8677ef9a8c7a"
},
{
"path": "/dev/nvme0n1p5",
"tags": {
"PARTUUID": "69712eb4-be52-4618-ba46-e317d6d3d76e"
},
"type": "db"
}
],
"41": [
{
"devices": [
"/dev/nvme1n1p13"
],
"name": "osd-block-97bce07f-ae98-4fdb-83a9-9fa2f35cee60",
"tags": {
"ceph.crush_device_class": "None",
},
"type": "block",
"vg_name": "ceph-c1d48671-2a33-4615-95e3-cc1b18783f0c"
}
],
"9": [
{
"devices": [
"/dev/sdf"
],
"name": "osd-block-35323eb8-17c1-460d-8cc5-565f549e6991",
"tags": {
"ceph.crush_device_class": "None",
"ceph.db_device": "/dev/nvme0n1p7",
"ceph.wal_device": "/dev/nvme0n1p8",
},
"type": "block",
"vg_name": "ceph-9488e8b8-ec18-4860-93d3-6a1ad91c698c"
},
{
"path": "/dev/nvme0n1p7",
"tags": {
"PARTUUID": "ef0e9588-2a20-4c2c-8b62-d73945e01322"
},
"type": "db"
}
]
}
Required output:
osd.7 /dev/sde /dev/nvme0n1p5 /dev/nvme0n1p6
osd.41 /dev/nvme1n1p13 n/a n/a
osd.9 /dev/sdf /dev/nvme0n1p7 /dev/nvme0n1p7
Problems:
When I try parsing using jq .[][].devices, I get null values:
$ cat json | jq .[][].devices
[
"/dev/sde"
]
null
[
"/dev/nvme1n1p13"
]
null
[
"/dev/sdf"
]
null
I can solve it via jq .[][].devices[]?.
However, this trick doesn't help me when I do want to see where there's no value (to print n/a instead):
$ cat json | jq '.[][].tags | ."ceph.db_device"'
"/dev/nvme0n1p5"
null
"/dev/nvme0n1p3"
null
null
"/dev/nvme0n1p7"
null
And finally, I try to create a table:
$ cat json | jq -r '["osd."+keys[]], [.[][].devices[]?], [.[][].tags."ceph.db_device" // ""] | #csv' | column -t -s,
"osd.7" "osd.41" "osd.9"
"/dev/sde" "/dev/nvme0n1p13" "/dev/sdf"
"/dev/nvme0n1p5" "/dev/nvme0n1p7"
So the obvious problem is that the 3rd row doesn't match the correct values.
And the final problem is how do I transpose it from columns to rows, as detailed in the required output?
Would this do what you want?
jq --raw-output '
to_entries[] | [
"osd." + .key,
( .value[0]
| .devices[],
( .tags
| ."ceph.db_device" // "n/a",
."ceph.wal_device" // "n/a"
)
)
]
| #tsv
'
osd.7 /dev/sde /dev/nvme0n1p5 /dev/nvme0n1p6
osd.41 /dev/nvme1n1p13 n/a n/a
osd.9 /dev/sdf /dev/nvme0n1p7 /dev/nvme0n1p8
Demo

Write json from bash pipe with several variable interpolations

I have this output from a pipe
{
"pipelineName": "pipelineName-AAAAQ6UFM",
"pipelineVersion": 2,
"stageStates": [
{
"stageName": "Approval",
"inboundTransitionState": {
"enabled": true
},
"actionStates": [
{
"actionName": "Approval",
"latestExecution": {
"status": "InProgress",
"token": "aaaa-aaaa-4316-a95f-2efc51d05761"
}
}
],
"latestExecution": {
"pipelineExecutionId": "fc73f4cb-c5a9-44a8-8fc1-d7e50259f485",
"status": "InProgress"
}
}
]
}
I am trying to write a json like this
{
"pipelineName": "pipelineName-AAAAQ6UFM",
"stageName": "Approval",
"actionName": "Approval",
"token": "aaaa-aaaa-4316-a95f-2efc51d05761",
"result": {
"status": "Approved",
"summary": ""
}
}
I could maybe set two variables from the pipeoutput with the read command but I don't know how to set both of them.
token
jq -r ' .stageStates[] | select(.stageName == "Approval") | .actionStates[0].latestExecution.token'
pipelineName
jq -r '.pipelineName'
Then I might be able to write the json with the jq command.
What would be the best way to do this ?
Based on your select(.stageName == "Approval"), it would appear that you are attempting to parameterize by the "stageName", so the following might be close to what you're looking for:
"Approval" as $stage
| { pipelineName, stageName: $stage, actionName: $stage }
+ (.stageStates[]
| select(.stageName == $stage).actionStates[]
| select(.actionName == $stage)
| {token: .latestExecution.token, result: {status: "Approved", summary: ""}})
You can use just jq to create the json:
jq ' .stageName = .stageStates[0].stageName
| .actionName = .stageStates[0].actionStates[0].actionName
| .token = .stageStates[0].actionStates[0].latestExecution.token
| .result = { "status": "Approved", "summary": "" }
| del(.stageStates, .pipelineVersion)
' file.json

Parsing json values using jq

I am trying to get values "en" of a JSON structure using jq on the linux command line.
find . -name "*.json" -exec jq -r \ '(input_filename | gsub("^\\./|\\.json$";"")) as $fname (map(.tags) | .[] | .[] | .tag.en ) as $tags | "\($fname)&\($tags)"' '{}' +
i have more than 5000 files, start from 0001.json 0002.json .. 5000.json
This is a simple file 0001.json
{
"result": {
"tags": [
{ "confidence": 100, "tag": { "en": "turbine" } },
{ "confidence": 64.8014373779297, "tag": { "en": "wind" } },
{ "confidence": 63.3033409118652, "tag": { "en": "generator" } },
{ "confidence": 7.27894926071167, "tag": { "en": "device" } },
{ "confidence": 7.01708889007568, "tag": { "en": "line" } }
]
},
"status": { "text": "", "type": "success" }
}
i get this result :
0001&turbine
0001&wind
0001&generator
0001&device
0001&line
jq: error (at ./0001.json:0): Cannot iterate over null (null)
Ouptut..
jq: error (at ./0002.json:0): Cannot iterate over null (null)
Output..
jq: error (at ./0003.json:0): Cannot iterate over null (null)
My Desired Output in one file from all json files results.
filename&enValue:confidenceValue
0001&turbine:100,wind:64,generator:63,device:7,line:7
0002&...
0003&...
0004&...
The jq filter you want can be written as follows:
(input_filename | gsub("^\\./|\\.json$";"")) as $fname
| ( [ .result.tags[] | [.tag.en, (.confidence | floor)] | join(":") ]
| join(",") ) as $tags
| "\($fname)&\($tags)"

ORION: How to reduce the response time for /v2/entities

I've deployed the iot stack with docker. These are the used containers:
fiware/orion:2.1.0
Command line options used: -corsOrigin __ALL -corsMaxAge 600 -dbhost mongo-orion -logLevel DEBUG -logForHumans -t 180-199
fiware/iotagent-json:1.9.0
GIVEN: The following device template:
{
"devices": [
{
"device_id": "sen-n",
"entity_name": "sen-n",
"entity_type": "sensor",
"transport": "HTTP",
"protocol": "IoTA-JSON",
"endpoint": "http://nodered:1880/notification",
"commands": [
{
"name": "ping",
"type": "command"
}
],
"attributes": [
{
"object_id": "status",
"name": "status",
"type": "Text"
}
],
"static_attributes": [
{
"name": "name",
"type": "Text",
"value": "Sensor n"
}
]
}
]
}
WHEN: Register a large amount of devices on the IoT agent running the following shell script:
# Bash execution example: sudo chmod +x run.sh --> ./run.sh 1100
# Sh execution example: sh run.sh 1100
#!/bin/bash
for n in $(seq "$1")
do
echo "Inserting $n device"
curl --request POST \
--url 'http://localhost:4041/iot/devices' \
--header 'Content-Type: application/json' \
--header 'fiware-service: test' \
--header 'fiware-servicepath: /test' \
--data '{"devices":[{"device_id":"sen-'$n'","entity_name":"sen-'$n'","entity_type":"sensor","transport":"HTTP","protocol":"IoTA-JSON","endpoint":"http://nodered:1880/notification","commands":[{"name":"ping","type":"command"}],"attributes":[{"object_id":"status","name":"status","type":"Text"}],"static_attributes":[{"name":"name","type":"Text","value":"Sensor '$n'"}]}]}'
done
AND: Trying to get these entities from Orion.
curl --request GET \
--url 'http://localhost:1026/v2/entities/?limit=1000' \
--header 'fiware-service: test' \
--header 'fiware-servicepath: /test'
THEN: The response time is too long. It is between 13447ms and 15516ms.
I have checked the Orion command line argument -cprForwardLimit equal to 0 but this causes the execution of commands not to work. It through the following 404 error.
orion | INFO#07:32:34 logMsg.h[1832]: Starting transaction from 172.18.0.1:38752/v1/updateContext
orion | DEBUG#07:32:34 rest.cpp[1414]: Got 417 of payload of 417 bytes
orion | INFO#07:32:34 rest.cpp[885]: Service Path 0: '/test'
orion | INFO#07:32:34 connectionOperations.cpp[94]: Database Operation Successful (query: { _id.id: "sen1", _id.type: "sensor", _id.servicePath: { $in: [ /^/test$/ ] } })
orion | INFO#07:32:34 connectionOperations.cpp[177]: Database Operation Successful (query: { query: { $or: [ { contextRegistration.entities: { $in: [ { id: "sen1", type: "sensor" }, { type: "sensor", id: "sen1" } ] } }, { contextRegistration.entities.id: { $in: [] } } ], expiration: { $gt: 1552548754 }, contextRegistration.attrs.name: { $in: [ "ping" ] }, servicePath: { $in: [ /^/test$/ ] } }, orderby: { _id: 1 } })
orion | INFO#07:32:34 connectionOperations.cpp[177]: Database Operation Successful (query: { query: { $or: [ { contextRegistration.entities: { $in: [ { id: "sen1", type: "sensor" }, { type: "sensor", id: "sen1" } ] } }, { contextRegistration.entities.id: { $in: [] } } ], expiration: { $gt: 1552548754 }, servicePath: { $in: [ /^/test$/ ] } }, orderby: { _id: 1 } })
orion | DEBUG#07:32:34 restReply.cpp[75]: Response 6: responding with 237 bytes, Status Code 200
orion | DEBUG#07:32:34 restReply.cpp[76]: Response payload: '{"contextResponses":[{"contextElement":{"type":"sensor","isPattern":"false","id":"sen1","attributes":[{"name":"ping","type":"command","value":""}]},"statusCode":{"code":"404","reasonPhrase":"No context element found","details":"sen1"}}]}'
orion | INFO#07:32:34 logMsg.h[1916]: Transaction ended
So, is there a way to reduce this response time without breaking the command execution?