FIWARE IoT-Agent
This section explains how to connect an NGSI-V2 broker with an NGSI-LD broker (Fiware Orion) through subscriptions to a FIWARE IoT-Agent. This connection between brokers arises as an alternative to the use of FIWARE Lepus due to the lack of testing and the experimental nature of this service.
Simulation Environment
An environment has been created with docker compose that deploys in an isolated way (on two independent networks) the architectures FIWARE NGSI-V2 and FIWARE NGSI-LD.
Services
Grouping the services according to the network or networks they belong to, we have:
- Network NGSI-V2
ngsiv2_network
- IoT-Agent
ngsiv2.iotagent
- Mongo DB
ngsiv2.mongodb
- Orion-V2
ngsiv2.orionv2
- IoT-Agent
- Network NGSI-LD
ngsild_network
- IoT-Agent
ngsild.iotagent
- Mongo DB
ngsild.mongodb
- LD Context
ngsild.context
- Orion-LD
ngsild.orionld
- Quantum Leap
ngsild.quantumleap
: Fiware data persistence service - CreateDB
ngsild.cratedb
: DB for Quantum Leap.
- IoT-Agent
- Both networks
ngsiv2_network
yngsild_network
- Jupyter Server
- NGINX
Before continuing...
Services checks
MongoDB connection
A quick way to check that the environment is correctly deployed and the different services communicate with each other is to verify the different databases and collections through MongoDB Compass:
MongoDB Compass
-
MongoDB-V2: localhost, port
27028
- IoT-Agent
- DB:
iotagent-json
- Colection:
groups
- Colection:
- DB:
- Context Broker: The database will appear when it has some entity.
- IoT-Agent
-
MongoDB-LD: localhost, port
27027
- IoT-Agent
- DB:
iotagent-json
- Colection:
groups
- Colection:
- DB:
- Context Broker
- DB:
orionld
- Colection:
contexts
- Colection:
- DB:
myOrion
- Colection
entities
- Colection
- DB:
- IoT-Agent
Communication with the IoT-Agents
By requesting the version from the IoT-Agents, it can be easily verified that they are correctly deployed and that they are visible among the different networks of the environment.
From jupyter-server
IoT-Agent NGSI-V2:
IoT-Agent NGSI-LD:
Terminal access to the containers
To access the containers from the terminal, the command docker exec
can be used.
Example
Steps for the connection between brokers
In theory, the procedure to connect two brokers through the IoT-Agent will be as follows:
-
Provisioning of a service group (IoT-Agent)
-
Devices creation (IoT-Agent)
-
Subscription (Context Broker)
-
Modification of devices values (IoT-Agent)
graph LR
fir(1º - Provisioning\n of a service group) -.-> A;
sec(2º - Provisioning\n of a service group) -.-> C;
thi(3º - Custom\n subscription V2 to LD) -.-> B;
four(4º - Modification\n of devices values) -.-> A;
subgraph NGSI-V2
A[IoT-Agent];
A --- B[Orion Broker];
end
subgraph NGSI-LD
B --> C[IoT-Agent\n];
C --- D[Orion Broker];
end
Simulations
Non-normalized data according to data-models
The objective of this example is to show the procedure to connect two brokers, setting aside the use of data-models as a normalizing element.
Property | Value |
---|---|
Type | example-type |
fiware-service | vrainIoTA |
All the code shown is designed to be run from the jupyter-server container
Provisioning of a group of services (IoT-Agent)
Creation of a service in the IoT-Agent with the attributes that all devices belonging to this service will have.
Through services, sets of devices can be grouped together and the creation of these can be automated.
Editable fields (in both versions)
- URL: http://ngsiv2.iotagent:4041/iot/services
- Headers:
- fiware-service: vrainIoTA
- fiware-servicepath: /
- apikey: vrain2gpepnvsb2uv4s40d59ov (value random, in principle the main requirement is to maintain the length and characters).
- cbroker: http://ngsiv2.orion:1026
- entity_type: example-type
- attributes: Modify according to the attributes of the devices. The structure of:
object_id
,name
andtype
must be maintained..
curl -iX POST \
'http://ngsiv2.iotagent:4041/iot/services' \
-H 'Content-Type: application/json' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' \
-d '{
"services": [
{
"apikey": "vrain2gpepnvsb2uv4s40d59ov",
"cbroker": "http://ngsiv2.orion:1026",
"entity_type": "example-type",
"resource": "/iot/json",
"attributes": [
{
"object_id": "t",
"name": "temperature",
"type": "Number"
},
{
"object_id": "h",
"name": "humidity",
"type": "Number"
},
{
"object_id": "f",
"name": "fillingLevel",
"type": "Number"
}
]
}
]
}'
curl -iX POST \
'http://ngsild.iotagent:4041/iot/services' \
-H 'Content-Type: application/json' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' \
-d '{
"services": [
{
"apikey": "vrainld2gpnvsb2uv4s40d59ov",
"cbroker": "http://ngsild.orion:1026",
"entity_type": "example-type",
"resource": "/iot/json",
"attributes": [
{
"object_id": "t",
"name": "temperature",
"type": "Number"
},
{
"object_id": "h",
"name": "humidity",
"type": "Number"
},
{
"object_id": "f",
"name": "fillingLevel",
"type": "Number"
}
]
}
]
}'
If everything goes well, we will receive a response like this:
Result in MongoDB
It should appear within the iotagent-json
database, a collection groups
and within this as many documents as services have been created.
Checks
The service groups can be obtained with the following request:
curl -X GET 'http://ngsiv2.iotagent:4041/iot/services' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' | jq .
If everything goes well, we will receive a response like this:
{
"count": 1,
"services": [
{
"commands": [],
"lazy": [],
"attributes": [
{
"object_id": "t",
"name": "temperature",
"type": "Number"
},
{
"object_id": "h",
"name": "humidity",
"type": "Number"
},
{
"object_id": "f",
"name": "fillingLevel",
"type": "Number"
}
],
"_id": "653900b475ac594b1cc9e607",
"resource": "/iot/json",
"apikey": "vrain2gpepnvsb2uv4s40d59ov",
"service": "vrainiota",
"subservice": "/",
"__v": 0,
"static_attributes": [],
"internal_attributes": [],
"entity_type": "example-type"
}
]
}
curl -X GET 'http://ngsild.iotagent:4041/iot/services' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' | jq .
If everything goes well, we will receive a response like this:
{
"count": 1,
"services": [
{
"commands": [],
"lazy": [],
"attributes": [
{
"object_id": "t",
"name": "temperature",
"type": "Number"
},
{
"object_id": "h",
"name": "humidity",
"type": "Number"
},
{
"object_id": "f",
"name": "fillingLevel",
"type": "Number"
}
],
"_id": "6540cb26101b6eba30d4d653",
"resource": "/iot/json",
"apikey": "vrainld2gpnvsb2uv4s40d59ov",
"service": "vrainiota",
"subservice": "/",
"__v": 0,
"static_attributes": [],
"internal_attributes": [],
"entity_type": "example-type"
}
]
}
Checklist - Before continuing...
To continue correctly with the example, you must have:
- IoT-Agent V2: Having a service created.
- Take note (to use later) of the service's:
- Attributes.
apikey
- Take note (to use later) of the service's:
- IoT-Agent LD: Having a service created.
- Take note (to use later) of the service's:
- Attributes.
- `apikey
- Take note (to use later) of the service's:
Aprovisionamiento de dispositivos (IoT-Agent)
The creation of devices can be done in two ways:
- Manual: By explicitly creating a device.
- Automated: By using a service (previously created) and modifying the values of a device from the service.
Manual Method
Info
This section is not necessary for the correct operation of the example. It will only be necessary to know the automated method to use it after creating the subscription and verifying that it works.
A specific device is added to the created service:
curl -iX POST \
'http://ngsiv2.iotagent:4041/iot/devices' \
-H 'Content-Type: application/json' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' \
-d '{
"devices": [
{
"device_id": "example001",
"entity_name": "example:example001",
"entity_type": "example-type",
"timezone": "Europe/Madrid"
}
]
}'
If everything goes well, we will receive a response like this:
This process only adds a device in the IoT-Agent but does not modify the value of the attributes. To modify the device values, you must use the request of the automated method.
Automated method (through services)
This method fulfills two functions:
- Create a device (if it does not exist).
- Modify the values of its attributes.
URL Structure
Replace the values of: <iotagent_adress>
, <apikey>
y <device_id>
for the corresponding values.
Warning
The port for this request changes from 4041
to 7896
.
Checks
To check the creation and modification of the values of a device, it can be done directly through MongoDB.
Results in MongoDB
As a result of this operation, a new database orion-<fiware-service>
(orion-vrainiota) is created in mongodb with a entities
collection and within this a document per device.
As a result of this operation, a new database myOrion-<fiware-service>
(myOrion-vrainiota) is created in mongodb with a entities
collection and within this a document per device.
Subscription of Orion Context Broker V2 to the IoT-Agent LD
Finally, a custom subscription is created in the V2 broker, in this way, for each modification of the values of a device, the broker will send a POST request (just like the previous one) in an automated way.
In the httpCustom:url, you cannot put addresses with -
curl -iX POST \
'http://ngsiv2.orion:1026/v2/subscriptions' \
-H 'Content-Type: application/json' \
-H 'fiware-service: vrainIoTA' \
-H 'fiware-servicepath: /' \
-d '{
"description": "Reenvío datos entre brokers.",
"status": "active",
"subject": {
"entities": [
{
"idPattern": ".*",
"type": "example-type"
}
],
"condition": {
"attrs": [],
"notifyOnMetadataChange": true
}
},
"notification": {
"attrs": [],
"onlyChangedAttrs": false,
"attrsFormat": "normalized",
"httpCustom": {
"url": "http://ngsiv2.to-ngsild:7896/iot/json",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"qs": {
"i": "${id}",
"k": "vrainld2gpnvsb2uv4s40d59ov"
},
"json": {
"t": "${temperature}",
"h": "${humidity}",
"f": "${fillingLevel}"
}
}
}
}'
Analyzing in detail some elements of this request we have:
- URL: Points to the subscriptions of the V2 broker.
- fiware-service: Necessary for the subscription to work.
- fiware-servicepath: Necessary for the subscription to work.
- notification
- attrs: There is no need to specify attributes as they are later selected in the body of the request.
- httpCustom
- url: Points to the IoT-Agent LD. Since the V2 broker network does not have direct visibility to the LD network, this address points to the reverse proxy between both networks.
- qs:
- k: The
k
parameter refers to theapiKey
of the service in IoT-Agent of LD.
- k: The
- json: This is the body of the request. It relates the
id
of the attributes in the IoT-Agent LD (t
,h
andf
) with the attributes in the V2 broker (${temperature}
,${humidity}
and${fillingLevel}
).
Checks
To verify that the subscription is working, you simply need to modify the value of a device using the IoT-Agent or directly modify an attribute of an entity in the V2 broker. In this case, the first option is chosen through the IoT-Agent.
Note how the request points to the address of the IoT-Agent in V2.
curl -iX POST \
'http://ngsiv2.iotagent:7896/iot/json?k=vrain2gpepnvsb2uv4s40d59ov&i=example001' \
-H 'Content-Type: application/json' \
-d '{"t": 656, "h":87, "f": "40"}'
If everything goes well, we will receive a response like this:
After executing this request, we will observe how in MongoDB (both V2 and LD) the values of the device in question (example001
) appear or are modified.
References
FIWARE IoT-Agent - Github Each version (V2 or LD) is located in a different branch.