Error when invoke a PATCH command to Orion Context Broker - fiware

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)

Related

curl -X POST with JSON how can I filtered Integer with less then or greater then (API is from Zabbix)"

i try to make a "maintenance.get" on Zabbix and what I need is the current active maintenance. which just working is:
curl --noproxy '*' -H "Content-Type: application/json" -X POST http://local.zabbix.lan/api_jsonrpc.php -d'
{
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": "extend",
"search": {
"name": ["Auto_"]
},
"filter": {
"active_till": "1657562960"
}
}
},
"auth": "07fxxx574444444444a65034c6xxxxx0",
"id": 1
}
' | sed 's/","/\n/g'
{"jsonrpc":"2.0
result":[{"maintenanceid":"199
name":"Auto_Maintenance_2022-07-11_16:56:53\u00b4
maintenance_type":"0
description":"
active_since":"1657551360
active_till":"1657572960
tags_evaltype":"0
timeperiods":[{"timeperiodid":"199
timeperiod_type":"3
every":"1
month":"0
dayofweek":"64
day":"0
start_time":"64800
period":"3600
start_date":"0"}]},{"maintenanceid":"200
name":"Auto_Maintenance_2022-07-11_17:51:06
maintenance_type":"0
description":"
active_since":"1657554660
active_till":"1657558260
tags_evaltype":"0
timeperiods":[{"timeperiodid":"200
timeperiod_type":"3
every":"1
month":"0
dayofweek":"64
day":"0
start_time":"64800
period":"3600
start_date":"0"}]}],"id":1}
but I get the whole list. I would need set a greater than operator to get only the number greater from today (so date in the future). what I tried with my knowledge is that but unfortunately it does not work:
{
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": "extend",
"search": {
"name": ["Auto_"]
},
"filter": {
"active_till": {
">=": [1657562960]
}
}
},
"auth": "07f186572af264203ba65034c6cc83a0",
"id": 1
}

parse json response using ansible

I need to parse the json response from an API request using ansible and then take action on items returned in the response. Here is part of my ansible playbook -
```- name: Invoke Import API
uri:
url: "{{ atl_bitbucket_dataset_url }}/rest/api/1.0/migration/imports"
user: admin
password: "{{ atl_bitbucket_admin_password }}"
method: POST
follow_redirects: yes
force_basic_auth: yes
creates: "{{ atl_product_home_shared }}/data/migration/import/lock.file"
body: "{ \"archivePath\": \"{{ atl_bitbucket_dataset_url | basename }}\" }"
body_format: json
return_content: yes
register: response
until: response.status == 200
retries: 6
delay: 15
failed_when: response.response.json.state != 'INITIALISING'
- name: get status of import
debug: var=response```
and here is the json response i got on a previous run
```TASK [bitbucket_dataset_restore : get status of import] ************************
ok: [localhost] => {
"response": {
"attempts": 1,
"cache_control": "no-cache, no-transform",
"changed": false,
"connection": "close",
"content": "{\"id\":1,\"initiator\":{\"name\":\"admin\",\"emailAddress\":\"admin#yourcompany.com\",\"id\":1,\"displayName\":\"AdminIstrator\",\"active\":true,\"slug\":\"admin\",\"type\":\"NORMAL\",\"links\":{\"self\":[{\"href\":\"http://bbdc-test-loadbala-t6vnlr2363vl-1404860112.us-west-2.elb.amazonaws.com/users/admin\"}]}},\"nodeId\":\"e72aa995-5016-4b2c-80e8-edba5eda3ab4\",\"progress\":{\"percentage\":0},\"startDate\":1574803309090,\"state\":\"INITIALISING\",\"type\":\"com.atlassian.bitbucket.migration.import\",\"updateDate\":1574803309090}",
"content_type": "application/json;charset=UTF-8",
"cookies": {},
"cookies_string": "",
"date": "Tue, 26 Nov 2019 21:21:49 GMT",
"elapsed": 1,
"failed": false,
"failed_when_result": False,
"json": {
"id": 1,
"initiator": {
"active": True,
"displayName": "AdminIstrator",
"emailAddress": "admin#yourcompany.com",
"id": 1,
"links": {
"self": [
{
"href": "http://bbdc-test-loadbala-t6vnlr2363vl-1404860112.us-west-2.elb.amazonaws.com/users/admin"
}
]
},
"name": "admin",
"slug": "admin",
"type": "NORMAL"
},
"nodeId": "e72aa995-5016-4b2c-80e8-edba5eda3ab4",
"progress": {
"percentage": 0
},
"startDate": 1574803309090,
"state": "INITIALISING",
"type": "com.atlassian.bitbucket.migration.import",
"updateDate": 1574803309090
},
"msg": "OK (unknown bytes)",
"redirected": False,
"status": 200,
"transfer_encoding": "chunked",
"url": "http://localhost:7990/rest/api/1.0/migration/imports",
"vary": "accept-encoding,x-auserid,cookie,x-ausername,accept-encoding",
"warnings": [
"The value True (type bool) in a string field was converted to u'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change."
],
"x_arequestid": "#XXAH7Kx1281x1x0",
"x_asen": "SEN-500",
"x_auserid": "1",
"x_ausername": "admin",
"x_content_type_options": "nosniff"
}
}```
I want to retrieve the value "state": "INITIALISING" and the "id": 1. I have tried various methods response.response.json.state or response['response']['json']['state']. And it has not worked. Can anyone help me on how i can retrieve those values so i can use in other tasks further down?
I was able to fix this by adding is defined. So my code looks like this -
failed_when: output is defined and output.json is defined and output.json.state != 'INITIALISING'

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?

Convert/Export JSON to CSV

JSON file:
"UserDetailList": [
{
"UserName": "citrix-xendesktop-ec2-provisioning",
"GroupList": [],
"CreateDate": "2017-11-07T14:20:14Z",
"UserId": "1234556",
"Path": "/",
"AttachedManagedPolicies": [
{
"PolicyName": "AmazonEC2FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
},
{
"PolicyName": "AmazonS3FullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}
],
"Arn": "arn:aws:iam::1234567890:user/citrix-xendesktop-ec2-provisioning"
},
{
"UserName": "rundeck-read-only-iam-permissions",
"GroupList": [],
"CreateDate": "2018-03-09T11:13:38Z",
"UserId": "AIDAJQOQGKISLCWDXG6EQ",
"Path": "/",
"AttachedManagedPolicies": [
{
"PolicyName": "IAMReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
}
],
"Arn": "arn:aws:iam::279052847476:user/rundeck-read-only-iam-permissions"
}
]
with
jq -r '.UserDetailList[] | [.UserName] | #csv' output.json > fileout2.csv
I can get
citrix-xendesktop-ec2-provisioning"
"rundeck-read-only-iam-permissions"
How to get IAM policies for these 2 users, i need to extract AmazonEC2FullAccess and AmazonS3FullAccess under AttachedManagedPolicies ?
so output can be
citrix-xendesktop-ec2-provisioning",AmazonEC2FullAccess
citrix-xendesktop-ec2-provisioning",AmazonS3FullAccess
rundeck-read-only-iam-permissions,IAMReadOnlyAccess
The trick is to extract .UserName as a variable before iterating over the inner array:
.UserDetailList[]
| .UserName as $u
| .AttachedManagedPolicies[]
| [$u, .PolicyName]
| #csv
Of course this assumes valid JSON input.

Commands in IotAgent Ultralight 2.0 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).