I want to process sensor data into a time series database via FIWARE ORION CONTEXT BROKER. However, instead of writing each data individually, I want to write it collectively as a 1-minute time series. Is something like this possible?
Could you help me? What path should I follow?
You need to split this problem into separate parts. Firstly define the payload of your batch operation. If the device can collect a series of readings and then deliver them as NGSI you can use the /v2/op/update/ for NGSI-v2 or /ngsi-ld/v1/entityOperations/upsert for NGSI-LD
For NGSI-v2 it would be something like
curl -L -X POST 'http://localhost:1026/v2/op/update/' \
-H 'Content-Type: application/json' \
--data-raw '{
"actionType":"append",
"entities":[
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"temperature": {
"type": "Property",
"value": 21,
"metadata":{
"unitCode": "CEL",
"TimeInstant": {
"type": "DateTime",
"value": "XXXX-XXX-XXXXX"
}
}
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"temperature": {
"type": "Property",
"value": 27,
"metadata":{
"unitCode": "CEL",
"TimeInstant": {
"type": "DateTime",
"value": "XXXX-XXX-XXXXX"
}
}
}
}
]
}'
For NGSI-LD it would be something like this:
curl -L -X POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/upsert' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/ngsi-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '[
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"temperature": {
"type": "Property",
"value": 21,
"unitCode": "CEL",
"observedAt": "XXXXX-XXXX-XXXXXX"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"temperature": {
"type": "Property",
"value": 27,
"unitCode": "CEL",
"observedAt": "XXXXX-XXXX-XXXXXX"
}
}
]'
The important thing here is to include the observedAt or TimeInstant in the payload so that it can be passed when creating a subscription into QuantumLeap (amend the fiware-service to the correct Tenant:
curl -iX POST \
'http://localhost:1026/v2/subscriptions/' \
-H 'Content-Type: application/json' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-d '{
"description": "Notify QuantumLeap of temperature changes",
"subject": {
"entities": [
{
"idPattern": "TemperatureSensor.*"
}
],
"condition": {
"attrs": [
"count"
]
}
},
"notification": {
"http": {
"url": "http://quantumleap:8668/v2/notify"
},
"attrs": [
"temperature"
],
"metadata": ["dateCreated", "TimeInstant"]
},
"throttling": 1
}'
Now it could be the case that you have a device writing to a file and periodically uploading a batch of readings. In this case you can create a Custom IoT Agent which deciphers the payload and transforms each reading into a batch upsert request - an example can be found in this FIWARE Video on YouTube.
The steps are always the same:
Ingest the payload holding the readings (in format X)
Transform format X to an in-memory representation.
Tweak the representation into the entities part of an NGSI request
Send the upsert to the context broker.
The subscription to QuantumLeap will persist the data to a database where you can make time-series queries. The FIWARE Tutorial will cover the steps.
Now if you are using NGSI-LD you can still use QuantumLeap, but you could also look at using the Temporal interface directly. More details in the video here
Related
I've trying to process a file that uploads+renders fine on the demo autodesk viewer (i.e. viewer.autodesk.com). The GetManifest result has a progress of "complete" but a status of "failed". If I dump the contents of the GetManifest() call I get the following which has Unrecoverable exit code from extractor: -1073741829 in the message. Wondering why it completes and renders on the online Autodesk viewer. The translation completes w\ "success", but when I try and get the manifest (so that I can download the derivatives), it fails on the GetManifest() call.
? manifest.ToString()
"{
\r\n "urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6a2FodWFtb2RlbHMvOWNjNjA2Njg2NGIwNDViNDg5NjhhNDMxNjI1NmEzNTMuSUZD",
\r\n "derivatives": [
\r\n {
\r\n "hasThumbnail": "false",\r\n "name": "LMV Bubble",\r\n "progress": "complete",\r\n "messages": [
\r\n {\r\n "type": "error",
\r\n "message": "Unrecoverable exit code from extractor: -1073741829",
\r\n "code": "TranslationWorker-InternalFailure"\r\n }\r\n ],\r\n
"outputType": "svf",\r\n "status": "failed"\r\n }\r\n ],
\r\n "hasThumbnail": "false",\r\n "progress": "complete",\r\n "type": "manifest",\r\n "region": "US",\r\n "version": "1.0",\r\n "status": "failed"\r\n}"
Since this IFC model is IFC4, please use the modern conversion method instead.
curl --location --request POST 'https://developer.api.autodesk.com/modelderivative/v2/designdata/job' \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--header 'x-ads-force: true' \
--data'{
"input": {
"urn": "{URN}"
},
"output": {
"formats": [
{
"type": "svf",
"views": [
"3d"
],
"advanced": {
"conversionMethod": "modern"
}
}
]
}
}'
I would like to make a httpCustom payload in OCB but no replace info properly. I think i have tested all the ways i know but no results, someone who could help me. This is my code:
"notification": {
"httpCustom": {
"url": "http://xxxx.xxxx.xxxx:8080/api/v1/telemetry",
"payload": "[{ %22temperature%22: %22${id}%22, %22humidity%22: %22${humidity}%22, %22battery%22: %22${battery}%22 }]"
},
"attrs": [
"temperature","humidity","battery"
]
},
I have no error when i do subscription, but when i test in my end point no replace for the macros ${...}, the payload take object information compose but with no values.
I have test to write/send ${id} as then value of a field in payload and no substitution at all. Test it with URL encode and %22 and no success, I think could be disable substitution ? but i have check it and it has FALSE value.
This is a http response:
{
"method": "POST",
"path": "/",
"query": {},
"headers": {
"x-forwarded-for": "3.124.211.58",
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "83efe9565d48d8bc8cf298d7786b8042.m.pipedream.net",
"x-amzn-trace-id": "Root=1-5f1bddce-7f2b4277458e77b98c0920d1",
"content-length": "54",
"user-agent": "orion/2.1.0 libcurl/7.29.0",
"fiware-service": "example",
"fiware-servicepath": "/example",
"accept": "application/json",
"content-type": "application/json",
"fiware-correlator": "a7fcfe32-ce47-11ea-9723-0242ac14000a",
"ngsiv2-attrsformat": "custom"
},
"bodyRaw": "[{ \"temperature\": \"\", \"humidity\": \"\", \"battery\": \"\" }]",
"body": [
{
"temperature": "",
"humidity": "",
"battery": ""
}
]
}
Orion VersiĆ³n: 2.1.0 and tested in 2.4.0
Any help ? Thanks in advance !!
I have done the following test, with Orion 2.4.0. Orion database is empty before starting the test.
First, create this subscription:
curl -v localhost:1026/v2/subscriptions -s -S -H 'Content-Type: application/json' -d #- <<EOF
{
"subject": {
"entities": [
{
"id": "Device1",
"type": "Device"
}
]
},
"notification": {
"httpCustom": {
"url": "http://localhost:1027/api/v1/telemetry",
"payload": "[{ %22temperature%22: %22\${id}%22, %22humidity%22: %22\${humidity}%22, %22battery%22: %22\${battery}%22 }]"},
"attrs": [
"temperature","humidity","battery"
]
}
}
EOF
Next, start a listining process at port 1027:
nc -l -p 1027
Next, create entity as follows (which triggers a notification):
curl localhost:1026/v2/entities -s -S -H 'Content-Type: application/json' -d #- <<EOF
{
"id": "Device1",
"type": "Device",
"temperature": {
"value": 23,
"type": "Number"
},
"humidity": {
"value": 99,
"type": "Number"
},
"battery": {
"value": 15,
"type": "Number"
}
}
EOF
What I get in nc is:
POST /api/v1/telemetry HTTP/1.1
Host: localhost:1027
User-Agent: orion/2.4.0 libcurl/7.52.1
Fiware-Servicepath: /
Accept: application/json
Content-Length: 65
Content-Type: text/plain; charset=utf-8
Fiware-Correlator: 4ae608b0-d248-11ea-81de-000c29df7908
Ngsiv2-AttrsFormat: custom
[{ "temperature": "Device1", "humidity": "99", "battery": "15" }]
which is the expected result, with replacements.
Next, restart the listening process and update the entity this way (triggering a new notification):
curl localhost:1026/v2/entities/Device1/attrs?options=forcedUpdate -s -S -H 'Content-Type: application/json' -d #- <<EOF
{
"temperature": {
"value": 32,
"type": "Number"
},
"humidity": {
"value": 79,
"type": "Number"
},
"battery": {
"value": 25,
"type": "Number"
}
}
EOF
and I get now in nc:
POST /api/v1/telemetry HTTP/1.1
Host: localhost:1027
User-Agent: orion/2.4.0 libcurl/7.52.1
Fiware-Servicepath: /
Accept: application/json
Content-Length: 65
Content-Type: text/plain; charset=utf-8
Fiware-Correlator: 66278dd8-d248-11ea-822d-000c29df7908
Ngsiv2-AttrsFormat: custom
[{ "temperature": "Device1", "humidity": "79", "battery": "25" }]
Conclusion: according my tests, Orion is working as expected.
I'd suggest to have a close look to the steps above and try to identify any possible diference comparing with your case. Note the \$ in the subscription creation payload: it is needed to avoid bash vars replacement in curl. Maybe you are facing a similar problem? You can check how your subscription is with GET /v2/subscriptions or checking directly in the database (csubs collection).
Looking at the documentation for the Forge Post Job. The examples show that region is a sub object of destination. However the docs seem to show that they are on the same level.
Doc was uploaded as image.
Curl Request Example:
curl -X 'POST' \
[![enter image description here][2]][2]-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer PtnrvrtSRpWwUi3407QhgvqdUVKL'
-v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/job' \
-d
'{
"input": {
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bW9kZWxkZXJpdmF0aXZlL0E1LnppcA",
"compressedUrn": true,
"rootFilename": "A5.iam"
},
"output": {
"destination": {
"region": "us"
},
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}'
Thanks for reporting this.
I've let our Dev Portal team know to take a look and will get back to you once they fix this up. Thanks!
curl -X POST -vv -H "Fiware-Service: myHome" -H "Fiware-ServicePath: /environment" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
"devices": [
{
"device_id": "0000000000000000",
"entity_name": "BedRoomSensor",
"entity_type": "multiSensor",
"attributes": [
{ "object_id": "t", "name": "Temperature", "type": "celsius" },
{ "object_id": "h", "name": "Humidity", "type": "degrees" }
]
}
]
} 'http://localhost:4041/iot/devices'
I execute the above curl commmand in order to provision my device.However it doesn't show anything and the command never ends.
What i missunderstood?
I have solved the problem following the first two steps of this guide:http://fiwaretourguide.readthedocs.io/en/latest/connection-to-the-internet-of-things/how-to-read-measures-captured-from-iot-devices/
In the step-by-step guide these steps weren't described.
In the second step i change the protocol fielde as "MQTT".
Now whenever i request the measures from my device i take the correct value.
I'm trying to use Orion CB as Contex Provider for an IoT Agent in which I have registred a device with lazy attributes only.
On the IoT Agent I need to handle updateContext requests so I did a handler for these requests like this:
iotAgentLib.setDataUpdateHandler(updateContextHandler);
And in the updateContextHandler function I have only one instruction:
console.log(attributes);
In order to see if all the values I want to update have been received correctly.
Now if I do an update on one of the attributes of the entity represented by the device:
curl -i -X POST \
-H "fiware-service:service1" \
-H "fiware-servicepath:/subservice1" \
-H "X-Auth-Token:wNRwDwqYlLoLD8U9sFkTAEE6PfYMbQ" \
-H "Content-Type:application/json" \
-d \
'{
"contextElements": [
{
"id": "ncc_estimate",
"attributes": [
{
"name": "arrival",
"type": "string",
"value": "some_value"
}
]
}
],
"updateAction": "UPDATE"
} ' \
'http://{orion_address}/v1/updateContext'
What I see on the IoT Agent output console is:
time=2018-01-09T08:14:59.539Z | lvl=DEBUG | corr=2f4fdb0c-f515-11e7-86b2-0242ac110003 | trans=6ac5c35d-d7bf-419c-8f64-bc843b991d47 | op=IoTAgentNGSI.GenericMiddlewares | srv=service1 | subsrv=/subservice1 | msg=Body:
{
"contextElements": [
{
"type": "nccestimate",
"isPattern": "false",
"id": "ncc_estimate",
"attributes": [
{
"name": "arrival",
"type": "string",
"value": ""
}
]
}
],
"updateAction": "UPDATE"
}
Where as you can see the value field is empty, as I can also see from the console.log() output in the UpdateHandler function that is:
[ { name: 'arrival', type: 'string', value: '' } ]
It seems that Orion is deleting the value before sending it to the IoT Agent. What could be the problem? Am I wrong doing something?
edit:
Here is the response for the call to: /v1/registry/contextEntities/ncc_estimate
{"contextRegistrationResponses":[
{"contextRegistration":
{"entities":[
{
"type":"nccestimate",
"isPattern":"false",
"id":"ncc_estimate"
}
],
"attributes":[
{
"name":"transport_type",
"type":"string",
"isDomain":"false"
},
{
"name":"arrival",
"type":"string",
"isDomain":"false"
}
],
"providingApplication":"http://192.168.199.151:4044"}
}
]}
edit2:
This is what Orion is sending to the iot agent when performing the updateContext operation described before:
POST //updateContext HTTP/1.1
User-Agent: orion/1.10.0-next libcurl/7.19.7
Host: 192.168.199.151:4044
fiware-service: service1
Fiware-ServicePath: /subservice1
X-Auth-Token: M62UkJc7yKX5aQwaHrsODfIrV4Ou85
Accept: application/json
Content-length: 169
Content-type: application/json; charset=utf-8
Fiware-Correlator: 42561e9a-f615-11e7-8610-0242ac110003
{"contextElements":[{"type":"nccestimate","isPattern":"false","id":"ncc_estimate","attributes":[{"name":"arrival","type":"string","value":""}]}],"updateAction":"UPDATE"}
As you can see the "value" field for the attribute is empty.
I'm using Orion version 1.10.0 and iot agent node lib version 2.5.1.
I have done the following test using CB same version as yours (i.e. 1.10.0)
First, create a registration as the one that IOTA would create:
(curl -s -S localhost:1026/v1/registry/registerContext -H "fiware-service:service1" -H "fiware-servicepath:/subservice1" -H 'Content-Type: application/json' -d #- | python -mjson.tool) <<EOF
{
"contextRegistrations": [
{
"entities": [
{
"type": "nccestimate",
"isPattern": "false",
"id": "ncc_estimate"
}
],
"attributes": [
{
"name": "transport_type",
"type": "string",
"isDomain": "false"
},
{
"name": "arrival",
"type": "string",
"isDomain": "false"
}
],
"providingApplication": "http://localhost:4044"
}
],
"duration": "P1M"
}
EOF
Next, check that it is exactly the same registration shown in the question post (except by the providingApplication, that points to localhost):
curl localhost:1026/v1/registry/contextEntities/ncc_estimate -s -S -H "fiware-service:service1" -H "fiware-servicepath:/subservice1" -H 'Accept: application/json' | python -mjson.tool
which response is
{
"contextRegistrationResponses": [
{
"contextRegistration": {
"attributes": [
{
"isDomain": "false",
"name": "transport_type",
"type": "string"
},
{
"isDomain": "false",
"name": "arrival",
"type": "string"
}
],
"entities": [
{
"id": "ncc_estimate",
"isPattern": "false",
"type": "nccestimate"
}
],
"providingApplication": "http://localhost:4044"
}
}
]
}
Next, run nc process at localhost on providingApplication port.
nc -l -p 4044
Once the setup is done, let's test first with an update based on the one in the question.
curl -s -S -X POST http://localhost:1026/v1/updateContext -H "fiware-service:service1" -H "fiware-servicepath:/subservice1" -H "Content-Type:application/json" -d #- <<EOF
{
"contextElements": [
{
"id": "ncc_estimate",
"attributes": [
{
"name": "arrival",
"type": "string",
"value": "some_value"
}
]
}
],
"updateAction": "UPDATE"
}
EOF
In this case, Orion doesn't recognized the registration and returns a Not Found response:
{
"contextResponses": [{
"contextElement": {
"type": "",
"isPattern": "false",
"id": "ncc_estimate",
"attributes": [{
"name": "arrival",
"type": "string",
"value": ""
}]
},
"statusCode": {
"code": "404",
"reasonPhrase": "No context element found",
"details": "ncc_estimate"
}
}]
}
In other words, Orion is not forwarding the response. I don't know why in your case is forwarded and leaves a trace in IOTA log file.
Next test uses the same request but adding a type field for the entity.
curl -s -S -X POST http://localhost:1026/v1/updateContext -H "fiware-service:service1" -H "fiware-servicepath:/subservice1" -H "Content-Type:application/json" -d #- <<EOF
{
"contextElements": [
{
"id": "ncc_estimate",
"type": "nccestimate",
"attributes": [
{
"name": "arrival",
"type": "string",
"value": "some_value"
}
]
}
],
"updateAction": "UPDATE"
}
EOF
In this case, the request is forwarded and I get this in the nc terminal.
POST //updateContext HTTP/1.1
User-Agent: orion/1.10.0 libcurl/7.38.0
Host: localhost:4044
fiware-service: service1
Fiware-ServicePath: /subservice1
Accept: application/json
Content-length: 179
Content-type: application/json; charset=utf-8
Fiware-Correlator: 42e75f8a-fa0d-11e7-93f1-000c29173617
{"contextElements":[{"type":"nccestimate","isPattern":"false","id":"ncc_estimate","attributes":[{"name":"arrival","type":"string","value":"some_value"}]}],"updateAction":"UPDATE"}
Note the some_value in the response. Orion seems to be progressing correctly the request in this case.
EDIT: according to user's feedback, entity type solved the problem. We are highlighting it in the documentation regarding Context Providers:
You should include entity type in the query/update in order for the ContextBroker to be able to forward to Context Providers