I'm running the Fiware IoT Agent example locally. The plan is to hook this up to some sort of Device and make a demo. I'm using request bin to inspect the requests sent from the IoT Agent.
After starting the environment with ./services start
I'm calling this shell script to register a bell device in the agent and then trigger the "ring" command.
curl -iX POST \
'http://localhost:4041/iot/devices' \
-H 'Content-Type: application/json' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-d '{
"devices": [
{
"device_id": "bell001",
"entity_name": "urn:ngsi-ld:Bell:001",
"entity_type": "Bell",
"protocol": "PDI-IoTA-UltraLight",
"transport": "HTTP",
"endpoint": "https://requestbin.fullcontact.com/zhygotzh/iot/bell001",
"commands": [
{ "name": "ring", "type": "command" }
],
"static_attributes": []
}
]
}
'
curl -iX POST \
'http://localhost:4041/v1/updateContext' \
-H 'Content-Type: application/json' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-d '{
"contextElements": [
{
"type": "Bell",
"isPattern": "false",
"id": "urn:ngsi-ld:Bell:001",
"attributes": [
{ "name": "ring", "type": "command", "value": "" }
],
"static_attributes": []
}
],
"updateAction": "UPDATE"
}'
This works well, I'm getting a 200 response and I can see the request in request bin.
$ ./setup-ul.sh
HTTP/1.1 201 Created
X-Powered-By: Express
Fiware-Correlator: 8298b65a-8550-4b6e-8a4d-21bc32abdf8a
Content-Type: application/json; charset=utf-8
Content-Length: 2
ETag: W/"2-vyGp6PvFo4RvsFtPoIWeCReyIC8"
Date: Fri, 29 Mar 2019 11:34:05 GMT
Connection: keep-alive
{}HTTP/1.1 200 OK
X-Powered-By: Express
Fiware-Correlator: c79a1146-05d8-4eb1-8e1c-bf19661cb403
Content-Type: application/json; charset=utf-8
Content-Length: 208
ETag: W/"d0-6+Ce6hwRVmP90ZI667iON6zHtdA"
Date: Fri, 29 Mar 2019 11:34:07 GMT
Connection: keep-alive
{"contextResponses":[{"contextElement":{"attributes":[{"name":"ring","type":"command","value":""}],"id":"urn:ngsi-ld:Bell:001","isPattern":false,"type":"Bell"},"statusCode":{"code":200,"reasonPhrase":"OK"}}]}
However, the request is in the Ultra Light format. I would prefer the JSON format. So I figured I'd just replace the image in the docker compose file.
iot-agent:
image: fiware/iotagent-ul:1.8.0
hostname: iot-agent
Gets changed to
iot-agent:
image: fiware/iotagent-json
hostname: iot-agent
in docker-compose.yml
.
Now when I try the same thing with the updated docker-compose file I get the following result:
$ ./setup.sh
HTTP/1.1 201 Created
X-Powered-By: Express
Fiware-Correlator: 69d6a6ad-a44a-4e57-87dd-4e512d499fee
Content-Type: application/json; charset=utf-8
Content-Length: 2
ETag: W/"2-vyGp6PvFo4RvsFtPoIWeCReyIC8"
Date: Fri, 29 Mar 2019 11:44:36 GMT
Connection: keep-alive
{}HTTP/1.1 400 Bad Request
X-Powered-By: Express
Fiware-Correlator: 6c9a28b5-0505-456c-bcdb-841df2bc6f62
Content-Type: application/json; charset=utf-8
Content-Length: 388
ETag: W/"184-RqfzTJc6iD9nXX3kAbxZqwruJC0"
Date: Fri, 29 Mar 2019 11:44:37 GMT
Connection: keep-alive
{"contextResponses":[{"contextElement":{"contextElements":[{"type":"Bell","isPattern":"false","id":"urn:ngsi-ld:Bell:001","attributes":[{"name":"ring","type":"command","value":""}],"static_attributes":[]}],"updateAction":"UPDATE"},"statusCode":{"code":400,"reasonPhrase":"HTTP_COMMAND_RESPONSE_ERROR","details":"There was an error in the response of a device to a command [400 ]:null"}}]}
This seems to be the relevant part: There was an error in the response of a device to a command [400 ]:null
. Does this mean that the IoT Agent was expecting some more specific response from the "device"?
The request can be seen in request bin, so it worked that far. But why does the agent think there was a problem? Does it expect some specific response format?
I've tried chaing the "protocol" in the device registration step to "PDI-IoTA-JSON" as well. That didn't help.
The problem is that the IoT Agent assumes that the device will respond with JSON. Requestbin's default answer is the string "ok". This caused a crash in the agent.
The request is successful if the device returns {}
, and it's even more successful if it returns some info on the result of the command. E.g.
{
"ring": "successfully rung"
}