I'm following this example to create a simple scenario where I register a new device into the IoT Agent and it forwards it to the Context Broker. Then I want to check if the created device exists in the Context Broker, and I can seem to find it.
These are the steps I'm doing:
1. using Postman I'm sending a post request to the IoT Agent:
url: http://eidas5.lab.fi-ware.org:5371/iot/devices
headers:
APIKEY:4jggokgpepnvsb2uv4s40d59ov
Fiware-Service:openiot
Fiware-ServicePath:/
Content-Type:application/json
Accept:application/json
body:
{
"devices": [
{ "device_id": "DEV_ID",
"entity_name": "ENTITY_ID",
"entity_type": "thing",
"protocol": "PDI-IoTA-UltraLight",
"timezone": "Europe/Madrid",
"attributes": [
{ "object_id": "t",
"name": "temperature",
"type": "int"
} ],
"static_attributes": [
{ "name": "att_name",
"type": "string",
"value": "value"
}
]
}
]
}
Then I confirm that the device is registered with a GET request to the url http://eidas5.lab.fi-ware.org:5371/iot/devices/DEV_ID
request headers:
APIKEY:4jggokgpepnvsb2uv4s40d59ov
Fiware-Service:openiot
Fiware-ServicePath:/
Content-Type:application/json
Accept:application/json
everything seems ok so far, now I want to check where this device is in the context broker:
According to the docs:
Devices will be represented as NGSI entities in the ContextBroker at 130.206.80.40:1026 (within the FIWARE service-path "OpenIoT").
So with a GET request I should be able to see the new device,but I can't. I even tryed using the fiware-servicepath and fiware-service headers as above, and I can't find it.
Any advice on this?
fiware-service should be open-iot and fiware-servicepath /
have a look at
http://fiwaretourguide.readthedocs.io/en/latest/connection-to-the-internet-of-things/how-to-read-measures-captured-from-iot-devices/
Related
I'm having a hard time understanding how context providers work in the Orion Context Broker.
I followed the examples in the step-by-step guide written by Jason Fox. However, I still do not exactly get what happens in the background and how the context broker exactly creates the POST from the registration. Here is what I am trying to do:
I do have a WeatherStation that provides sensor data for a neighborhood.
{
"id": "urn:ngsi-ld:WeatherStation:001",
"type": "Device:WeatherStation",
"temperature": {
"type": "Number",
"value": 20.5,
"metadata": {}
},
"windspeed": {
"type": "Number",
"value": 60.0,
"metadata": {}
}
}
Now I like the WeatherStation to be a context provider for all buildings.
{
"id": "urn:ngsi-ld:building:001",
"type": "Building"
}
Here is the registration that I try to use.
{
"id": null,
"description": "Random Weather Conditions",
"provider": {
"http": {
"url": "http://localhost:1026/v2"
},
"supportedForwardingMode": "all"
},
"dataProvided": {
"entities": [
{
"id": "null",
"idPattern": ".*",
"type": "Building",
"typePattern": null
}
],
"attrs": [
"temperature",
"windspeed"
],
"expression": null
},
"status": "active",
"expires": null,
"forwardingInformation": null
}
The context broker accepts both entities and the registration without any error.
Since I have a multi-tenant setup I use one fiware_service for the complete neighborhood but every building would later have a seperate fiware_servicepath. Hence, the weatherstation has a different servicepath than the building. Although I also tried to put them both on the same path.
For now I used the same headers for all entities.
{
"fiware-service": "filip",
"fiware-servicepath": "/testing"
}
Here is the log of the context broker (version: 3.1.0):
INFO#2021-09-23T19:17:17.944Z logTracing.cpp[212]: Request forwarded (regId: 614cd2b511c25270060d873a): POST http://localhost:1026/v2/op/query, request payload (87 bytes): {"entities":[{"idPattern":".*","type":"Building"}],"attrs":["temperature","windspeed"]}, response payload (2 bytes): [], response code: 200
INFO#2021-09-23T19:17:17.944Z logTracing.cpp[130]: Request received: POST /v2/op/query?options=normalized%2Ccount&limit=1000, request payload (55 bytes): {"entities": [{"idPattern": ".*", "type": "Building"}]}, response code: 200
The log says that it receives the request and forwards it as expected. However, as I understand it this would simply point to the same building entity again. Hence, it is somehow a circular forwarding. I also cannot tell anything about the headers of the request.
I do not understand how the forwarded request from the building can actually query the weather station for information. When I query my building I still only receive the entity with no own properties:
{
"id": "urn:ngsi-ld:building:001",
"type": "Building"
}
I also tried to vary the url of the registration but with no success.
Is this scenario actually possible with the current implementation? It would be very useful
Is there any example for this including also the headers?
I know that I could simply use reference but that would put more work on the user.
Thanks for any help on this.
It is messy, but you could achieve this via a subscription. Hold the weather station as a separate entity in the context broker and poll or push updates into the entity. The subscription would fire whenever the data changes and make two NGSI requests:
Find all entities which have a Relationship servicedBy=WeatherStationX
Run an upsert on all entities to add a Property to each entity:
{
"temperature" : {
"type" : "Property",
"value" : 7,
"unitCode": "CEL",
"observedAt": "XXXXX",
"providedBy": "WeatherStation1"
}
}
Where observedAt comes either from the payload of the weather station or the notification timestamp.
Within the existing IoT Agents, provisioning the link attribute allows a device to propagate measures to a second entity (e.g. this Thermometer entity is measuring temperature for an associated Building entity)
{
"entity_type": "Device",
"resource": "/iot/d",
"protocol": "PDI-IoTA-UltraLight",
..etc
"attributes": [
{"object_id": "l", "name": "temperature", "type":"Float",
"metadata":{
"unitCode":{"type": "Text", "value" :"CEL"}
}
}
],
"static_attributes": [
{
"name": "controlledAsset",
"type": "Relationship",
"value": "urn:ngsi-ld:Building:001",
"link": {
"attributes": ["temperature"],
"name": "providedBy",
"type": "Building"
}
}
]
}
At the moment the logic just links direct one-to-one, but it would be possible to raise a PR to check for an Array and update multiple entities in an upsert - the relevant section of code is here
I was reading the QuantumLeap docs and I was wondering how those Generic Enablers are integrated, I mean, I've deployed the docker containers and apparently are all running, in fact I've been able to create a device in the IoTagent-LoRaWAN with the POST request which I'm also able to retrieve with the GET request to http://localhost:4061/iot/devices; however and it's apparently receiving the info from TTN as the log shows:
fiware-iot-agent | {"timestamp":"2020-06-24T19:23:04.759Z","level":"info","message":"New message in topic"}
fiware-iot-agent | {"timestamp":"2020-06-24T19:23:04.760Z","level":"info","message":"IOTA provisioned devices:"}
fiware-iot-agent | {"timestamp":"2020-06-24T19:23:04.760Z","level":"info","message":"Decoding CaynneLPP message:AQIBbA=="}
fiware-iot-agent | {"timestamp":"2020-06-24T19:23:04.760Z","level":"error","message":"Could not cast message to NGSI"}
However ... there is a last error message that I don't know if could cause problems, "level":"error","message":"Could not cast message to NGSI"
Also ... I don't know how should I proced now with OrionCB and QuantumLeap because ... QuantumLeap docs talk about create an OrionCB subscription, but ... I had understood from OrionCB docs that subscriptions are created to follow a previously created entity, so .. should I create both?
Is QuantumLeap storing info from any created subscription in OrionCB? How can I tight an entity to that IoTagent-LoRaWAN device created?
Thank you all!
Well, It was apparently again a problem with docker-compose.yml file; it was not deploying correctly the mongoDB container thus OrionCB cannot connect to it.
When all containers are deployed the IoTagent should be able to create an new entity when you add a new device, then creating the proper subscription in OrionCB pointing the notifications to QuantumLeap should work:
{
"description": "Test subscription",
"subject": {
"entities": [
{
"idPattern": ".*",
"type": "Room"
}
],
"condition": {
"attrs": [
"temperature"
]
}
},
"notification": {
"http": {
"url": "http://quantumleap:8668/v2/notify"
},
"attrs": [
"temperature"
],
"metadata": ["dateCreated", "dateModified"]
},
"throttling": 5
}
I want to use IoT Agent JSON (https://github.com/telefonicaid/iotagent-json) with HTTP transport protocol instead of MQTT. Is it possible? How can I do it?
Thanks!
Yes, you cand o it, just follow the new github README secion where HTTP transport option is explained.
Cheers,
You only need a contiguration/template for all your devices. Such a configuration must specify the protocol is IoTA-JSON and the transport is HTTP. The request is sent to the nothbound interface of the Json IoT agent:
POST http://iota_host:iota_port/iot/services
Fiware-Service: <service>
Fiware-ServicePath: <subservice>
{
"services": [
{
"entity_type": "<default_entity_type>",
"protocol": "IoTA-JSON",
"transport": "HTTP",
"apikey": "<api_key>",
"attributes": [ "<common_active_attrs_if_any>" ],
"lazy": [ <common_lazy_attrs_if_any> ],
"commands": [ <common_commands_if_any> ],
"static_attributes": [ <common_static_attrs_if_any> ]
}
]
}
After that, you will be able to provision Json-based devices using Http transport:
POST http://iota_host:iota_port/iot/devices
Fiware-Service: <service>
Fiware-ServicePath: <subservice>
{
"devices": [
{
"device_id": "<device_id>",
"entity_name": "<entity_name>",
"entity_type": "<alternative_entity_type>",
"attributes": [ <additional_active_attrs_if_any> ],
"lazy": [ <additional_lazy_attrs_if_any> ],
"commands": [ <additional_commands_if_any> ],
"static_attributes": [ <additional_static_attrs_if_any> ]
}
]
}
Even, you could create a configuration/template without specifying the transport, i.e. the configuration/template will only relate to all the Json-based agents, independently of their transport, and then when provisioning a Json-based device, specify the transport.
How can we add security between Orion broker and Cepheus?
How can we use Cepheus with a protected Orion broker (pep is used to secure the access to the broker)?
Thanks and best regards.
Fiware-Cepheus currently does not act as an OAuth client and does not make requests to an IDM server to retrieve the OAuth token by itself.
However Fiware-Cepheus handles the three HTTP headers required by Orion Policy Enforcement Point (PEP) proxies : x-auth-token, fiware-servicepath and fiware-service.
Theses headers values can be set for either Cepheus Broker or Cepheus CEP from configuration settings.
For Cepheus Broker, this configuration is currently static. See Configuration section of the Admin manual.
remote.serviceName=tenant
remote.servicePath=test/example
remote.authToken=OAUTH_TOKEN
For Cepheus CEP, this configuration is more dynamic as it is part of the CEP rules provisioning and can be done independently for each outgoing event. See Configuration section of the User manual.
"out": [
{
"id": "FloorX",
"type": "Floor",
"attributes": [
{
"name": "temperature",
"type": "double",
"metadata": [
{
"name": "unit",
"type": "string"
}
]
}
],
"brokers": [
{
"url": "http://orion.fiware.org:3000",
"serviceName": "tenant",
"servicePath": "test/example",
"authToken": "OAUTH_TOKEN"
}
]
}
]
This question is very similar to Missing attributes on Orion CB Entity when registering device through IDAS but found no definitive answer there.
I have been trying FiWare to get UL2.0 via IDAS to the Orion CB working in the Fiware-Lab env:
using latest GitHub
https://github.com/telefonicaid/fiware-figway/tree/master/python-IDAS4
scripts
following the tutorials in particular
http://www.slideshare.net/FI-WARE/fiware-iotidasintroul20v2
I have a FI-WARE Lab account with token generated. Adapted the config.ini file:
[user]
# Please, configure here your username at FIWARE Cloud and a valid Oauth2.0 TOKEN for your user (you can use get_token.py to obtain a valid TOKEN).
username=MY_USERNAME
token=MY_TOKEN
[contextbroker]
host=130.206.80.40
port=1026
OAuth=no
# Here you need to specify the ContextBroker database you are querying.
# Leave it blank if you want the general database or the IDAS service if you are looking for IoT devices connected by you.
# fiware_service=
fiware_service=bus_auto
fiware-service-path=/
[idas]
host=130.206.80.40
adminport=5371
ul20port=5371
OAuth=no
# Here you need to configure the IDAS service your devices will be sending data to.
# By default the OpenIoT service is provided.
# fiware-service=fiwareiot
fiware-service=bus_auto
fiware-service-path=/
#apikey=4jggokgpepnvsb2uv4s40d59ov
apikey=4jggokgpepnvsb2uv4s40d59ov
[local]
#Choose here your System type. Examples: RaspberryPI, MACOSX, Linux, ...
host_type=MACOSX
# Here please add a unique identifier for you. Suggestion: the 3 lower hexa bytes of your Ethernet MAC. E.g. 79:ed:af
# Also you may use your e-mail address.
host_id=a0:11:00
I used the SENSOR_TEMP template, adding the 'protocol' field (PDI-IoTA-UltraLight which as the first problem I stumbled upon):
{
"devices": [
{ "device_id": "DEV_ID",
"entity_name": "ENTITY_ID",
"entity_type": "thing",
"protocol": "PDI-IoTA-UltraLight",
"timezone": "Europe/Amsterdam",
"attributes": [
{ "object_id": "otemp",
"name": "temperature",
"type": "int"
} ],
"static_attributes": [
{ "name": "att_name",
"type": "string",
"value": "value"
}
]
}
]
}
Now I can Register the device ok. Like
python RegisterDevice.py SENSOR_TEMP NexusPro Temp-Otterlo
and see it in Device List:
python ListDevices.py
I can send Observations like
python SendObservation.py Temp-Otterlo 'otemp|17'
But in the ContextBroker I see the Entity but never the measurements, e.g.
python GetEntity.py Temp-Otterlo
Gives
* Asking to http://130.206.80.40:1026/ngsi10/queryContext
* Headers: {'Fiware-Service': 'bus_auto', 'content-type': 'application/json', 'accept': 'application/json', 'X-Auth-Token': 'NULL'}
* Sending PAYLOAD:
{
"entities": [
{
"type": "",
"id": "Temp-Otterlo",
"isPattern": "false"
}
],
"attributes": []
}
...
* Status Code: 200
* Response:
{
"contextResponses" : [
{
"contextElement" : {
"type" : "thing",
"isPattern" : "false",
"id" : "Temp-Otterlo",
"attributes" : [
{
"name" : "TimeInstant",
"type" : "ISO8601",
"value" : "2015-10-03T14:04:44.663133Z"
},
{
"name" : "att_name",
"type" : "string",
"value" : "value",
"metadatas" : [
{
"name" : "TimeInstant",
"type" : "ISO8601",
"value" : "2015-10-03T14:04:44.663500Z"
}
]
}
]
},
"statusCode" : {
"code" : "200",
"reasonPhrase" : "OK"
}
}
]
}
I get an TimeInstant attribute strangely. I tried playing with settings of the .ini like fiware-service=fiwareiot, but to no avail. I am out of ideas. The documentation at the catalogue. for IDAS4
is talking about observations to be sent to port 8002 and setting "OpenIoT" service, but that failed as well.
Any help appreciated.
You should run "python SendObservation.py NexusPro 'otemp|17'" instead of "python SendObservation.py Temp-Otterlo 'otemp|17'".
The reason is that you are providing an observation at the southbound and then, the DEV_ID should be used.
The entity does not include an attribute until an observation is received so then it is normal you are not able to see it. Once you try the one above it should all work.
Cheers,