Using Cygnus to write in mongo db with no string - fiware

I'm trying to use Orion CB and Cygnus to write information about water quality and water consume and I need to write in float type. However it is impossible to me to know if there is any possibility to write this with float or double format.
Could someone tell me if this possibility exists?

As stated at FIWARE Orion documentation, you are free to specify your entities attributes using JSON format.
So, you will have your entity in the following format:
{
"id": "entityID",
"type": "entityType",
"attr_1": <val_1>,
"attr_2": <val_2>,
...
"attr_N": <val_N>
}
In which each <val_n> will be in the following format:
{
"type": <...>,
"value": <...>,
"metadata": <...>
}
Thus, you can have some entity described, for example, as:
{
"id": "sensor_ID",
"type": "room_sensor",
"temperature": {
"type": "float",
"value": 23.2
},
"noise": {
"type": "integer",
"value": 35
}
}
Therefore, you can use float or double as you want.

Related

FIWARE IoT Agent Framework: How to define a device with nested attributes in IoT Agent e.g geo:json?

I can't find how to define a device where its entity contains nested attributes.
The need is to pass gps coordinates from a device to an entity having geo:json (like urn:ngsi-ld:Shelf:unit001 in tutorial https://github.com/FIWARE/tutorials.Entity-Relationships)
Following the https://fiware-tutorials.readthedocs.io/en/latest/iot-over-mqtt/index.html the below
curl -iX POST \
'http://localhost:4041/iot/devices' \
...
-d '{
"devices": [
{
"device_id": "motion001",
"entity_name": "urn:ngsi-ld:Motion:001",
{ "object_id": "c", "name": "count", "type": "Integer" }
],
"static_attributes": [
...
creates the count attribute
{
"id": "Motion:001",
"type": "Motion",
"TimeInstant": {
"type": "DateTime",
"value": "2020-04-04T07:52:29.00Z",
"metadata": {}
},
...
"count": {
"type": "Integer",
"value": "12",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2020-04-04T07:52:29.00Z"
}
}
},
How to replace the count above in order to get the below outcome ?
"type": "geo:json",
"value": {
"type": "Point",
"coordinates": [13.3986,52.5547]
},
In all examples and documentation the attributes are defined in one level (not nested) https://iotagent-node-lib.readthedocs.io/en/latest/api/index.html.
Tses
Device measures are usually just numbers so for structured elements you either use the expression library or pass data as structured JSON using the IoT Agent for JSON.
That being said, improved GeoJSON support has recently been added to the IoT Agent library, so the following will work on *:latest IoT Agent docker images. According to the Documentation various input formats are now possible.
The defined type of any GeoJSON attribute can be any set to any of
the standard NGSI-v2 GeoJSON types - (e.g. geo:json, geo:point).
NGSI-LD formats such as GeoProperty, Point and LineString are
also accepted type values. If the latitude and longitude are
received as separate measures, the expression
language can be used to concatenate them.
"entity_type": "GPS",
"resource": "/iot/d",
"protocol": "PDI-IoTA-JSON", ..etc
"attributes": [
{
"name": "location",
"type": "geo:json",
"expression": "${#lng}, ${#lat}"
}
] }
For attributes and static_attributes which need to be formatted as
GeoJSON values, three separate input formats are accepted. Provided
the type is provisioned correctly, the value may be defined using
any of the following formats:
a comma delimited string
{ "name": "location", "value": "23, 12.5" }
an array of numbers
"name": "location",
"value": [23, 12.5]
}
an fully formatted GeoJSON object
{
"name": "location",
"value": {
"type": "Point",
"coordinates": [23, 12.5]
}
}
So if your device can send a comma separated long/lat string you should be fine.

Orion CB output regarding provisioned device

I have noticed that upon querying Orion CB, while it is working with provisioned devices and having IoT Agent receive HTTP and MQTT messages, it will always output all the values written in the quotation marks:
{
"id": "sensor_data",
"type": "Sensor",
"ActiveTime": {
"type": "Seconds",
"value": "17703",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.357Z"
}
}
},
"Distance": {
"type": "Number",
"value": "312",
"metadata": {
"TimeInstant": {
"type": "ISO8601",
"value": "2018-07-04T13:32:27.413Z"
}
}
}
}
However, if to work with only entities in Orion CB, it is possible to receive actual values (like in the example in the manual):
{
"id": "Room1",
"pressure": {
"metadata": {},
"type": "Integer",
"value": 720
},
"temperature": {
"metadata": {},
"type": "Float",
"value": 23
},
"type": "Room"
}
Sometimes, I need to receive the actual value from my sensor in order to format it and use in further applications, but they are in quotation marks, which makes it a little difficult.
Is it possible to somehow change?(maybe in device provisioning), or it really should be that way regarding devices?
Thanks in advance!
EDIT 1
This is the way I provisioned the device:
{
"devices": [
{
"device_id": "sensor_data",
"entity_name": "sensor_data",
"entity_type": "Sensor",
"transport": "MQTT",
"timezone": "Europe/Helsinki",
"attributes": [
{ "object_id": "act", "name": "ActiveTime", "type": "Seconds"},
{ "object_id": "dst", "name": "Distance", "type": "Number"}
]
}
]
}
And this is how the MQTT messages are sent from my sensor (I have set up the topics for IoT Agent to understand them)
/123456789/sensor_data/attrs/act 12
/123456789/sensor_data/attrs/dst 322
123456789 is the API Key I have set here.
This situation tipycally happens when IoT Agents uses NGSIv1 to push data to Context Broker, given that NGSIv1 always "string-fy" any attribute value. Recently, the ability to use NGSIv2 (which doesn't have this limitatino) was introduced in IoT Agents.
In order to solve your problem you have to:
Use a recent IOTA-UL version (the current one from master branch will work)
Enable NGSIv2 in configuration as explained in documentation. This is done in the config.js file:
config.iota = {
...
contextBroker: {
...
ngsiVersion: 'v2'
}
...
}
or using environament variable IOTA_CB_NGSI_VERSION=v2 for the IOTA-UL process.
Enable autocast as explained in documentation. This is done in config.js file:
config.iota = {
...
autocast: true,
...
}
or using environament variable IOTA_AUTOCAST=true for the IOTA-UL process.
Set the right type for each attribute at provision time. The documentation here) provides the right types:
Type "Number" for integer or float numbers
Type "Boolean" for boolean
Type "None" for null
Thus, in your case the provisioning for Distance is ok, but for ActiveTime you should use also Number as type.

Why does a numeric key in the JSON Structure always get displayed first

(Cannot summarize the problem in a single statement, hence the ambiguous title)
I create a JSON structure via Angular Typescript, wherein when a user interacts with certains parts of the component the JSON Structure gets updated.
Steps
Initially, the JSON under consideration is by default set to the following:
{
"keyword": {
"value": "product",
"type": "main"
}
}
For example, a user chooses some parameter Name. Once the user complies to certain steps in the UI, the JSON structure gets updated to the following:
{
"keyword": {
"value": "product",
"type": "main"
},
"Name": {
"value": " <hasProperty> Name",
"type": "dataprop"
}
}
Once the user selects a numeric value for a parameter like dryTime, the JSON gets updated to the following:
{
"20": { // WHY WOULD 20 be here?
"value": "<hasValue> 20",
"type": "fValue"
},
"keyword": {
"value": "Varnish",
"type": "main"
},
"Name": {
"value": " <hasProperty> Name",
"type": "dataprop"
},
"dryingTime": {
"value": " <hasProperty> dryingTime",
"type": "dataprop"
}
}
I understand that a JSON is an unordered data structure. But a previous implementation of something similar actually worked well, i.e., the value 20 here was 20.0 before and it was displayed after dryingTime in my JSON.
The order is critical for me as I parse all the Keys in the above mentioned JSON using a for loop and store it in an array. This array needs to show all the keys in the order of the User Interaction.
Where am I going wrong here if I decide to stay with JSON and not with an array to store such interactions?
Yes, JSON fields are unordered. JSON array is ordered.
If you want to keep the order of elements insterted, you could build your JSON like so:
{
"keyword": {
"value": "Varnish",
"type": "main"
},
"props": [
{
"name": "dryingTime",
"value": 20
},
{
"name": "anotherOrderedField",
"value": "fieldValue"
}
]
}

Seggregation of Json Schema Validation and Json Validation

I have a use case where I will take a json-schema as input, validate it, then keep in my system. Later I will get json data which I need to validate with above mentioned json-schema. given the scenario, I need to do two level of validations:
1. provided json-schema is valid or not.
2. Json is valid or not.
I am using json-schema-validator jar and could find only second level of validation, couldn't find json-schema validation in documentation. for example: lets say we have below sample json-schema:
{
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
so how to validate this json-schema itself is valid or not?
There is a working example here with the everit-org/json-schema implementation (just in case you want to use a maintained library):
How to validate a json schema against the version spec it specifies in Java
You have to validate schema against meta-schema: http://json-schema.org/draft-04/schema

JSON schema enum vs pattern for single value

I have an sample json:
{
"type": "persons",
"id": 2,
"attributes": {
"first": "something",
"second": "something else"
}
}
And I have to make a schema for it (using JSON API specs and JSON schema docs):
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"type": {
"type": "string",
"pattern": "^persons$"
},
"id": {
"type": "integer"
},
"attributes": {
"type": "object",
"properties": {...}
}
},
"required": ["type", "id", "attributes"]
}
And the question is: if the only acceptable value for "type" is "persons", should I use in schema pattern (like above) or enum like
"enum": ["persons"]
I couldn't get any clear answer from documentation, although in examples in specs enums are used for single values. So what's your opinion?
Ultimately, it doesn't really matter. Both will work and both are reasonable. That said, the most common approach I've seen is to use enum. Neither are perfect for readability, but I think enum is better for two reasons.
Using pattern requires two lines to express. Using enum requires only one because type is implied by the value in the array. Two lines are harder to read than one, so if that line is expressive enough, I say stick with one.
Not everyone is comfortable reading regex. enum might be more accessible for that reason.
Since draft-6 there is a new keyword called const for this use-case.
"type": {
"type": "string",
"const": "persons"
},
http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.3