Querying data
Relynk's core feature is its sensor data, and the '/query' API endpoint is the primary way to access it. This guide will explain the intricacies of the query endpoint and show you how to effectively retrieve the data you need. We will first go over the endpoint's schema and then provide examples of common use cases.
Prerequisites
This guide assumes that you have a basic understanding of the relationship between assets and sensors in Relynk. If you are unfamiliar with this concept, please read the Relationship between sensors and assets guide before proceeding.
Accessing the Query Endpoint
To create a query, you need to make a POST request to '/query' with a JSON body containing the query parameters. The JSON body must follow the structure defined below:
The query endpoint will return a maximum of 2,000 records at a time. If you need to retrieve more records, you will need to use the 'limit' and 'offset' parameters to split your query into multiple requests, please refer to Retrieving Large Amounts of Data for more information.
By default, the query endpoint returns data ordered by time in descending order, meaning the first returned record will be the most recent one in the database.
Filtering Data
You can use filters to narrow down the data returned by your query. Filters are structured as a list of objects, with each object representing a filter. Each filter has the following structure:
To create a filter, you need to specify the 'filter_on' parameter, which defines the type of filtering you want to do, and the 'values' list, which specifies the values you want to filter on. If you specify multiple values, the query will return data that matches any of them.
You need to specify at least one 'filter_on' parameter, and at least one value.
Also, if you filter on 'asset_id', the query will also include all child assets of the assets you are filtering on. For example, if you filter on a floor, the query will also return data for all the rooms on that floor.
Grouping Data
The 'group_on' parameter allows you to group the data by a particular field. For example, if you filter on a floor and want to get data for every room on that floor, you would specify 'group_on' as 'Room'. This will return data grouped by room, only for rooms that are children of the floor you filtered on.
If you do not supply any 'group_on' value then every sensor and measurement will be returned with no grouping. Useful if you would like to export all sensor data.
{#grouping-data-note}
When a grouping contains multiple data points, the API will provide the time-weighted average of all the data points within that group.
Moreover, the specific values assigned to the returned data points can vary based on the chosen grouping. If you group by asset type, such as 'Room' or 'Floor', the values 'group_asset_id,' 'group_asset_name,' and 'group_asset_type' will be populated. Conversely, if you group by any other criterion, the values 'group_sensor_id' and 'group_sensor_name' will be populated instead.
The following 'group_on' values are supported:
Understanding Resolution
The resolution parameter is used in conjunction with the concept of 'time buckets'. A time bucket is a time period that is used to group data together. For example, if you have a time bucket of 1 hour, then all data points that fall within that hour will be grouped together. The 'resolution' parameter is used to specify the size of the time buckets.
When used in combination with the 'group_on' parameter, the API endpoint will first group the data by the 'group_n' parameter, and then group the data within each group by the resolution parameter.
The following resolutions are supported:
:::asNestedObjects If 'is_timeseries' is set to false or 'only_latest_value' is set to true, the 'resolution' parameter is ignored.
:::
Retrieving Timeseries Data
The 'is_timeseries' parameter defines whether the returned data should be in timeseries format or not. If 'is_timeseries' is set to true, the data will be returned in timeseries format in time buckets based on the 'resolution' parameter. If not, the API will aggregate all the data down to a single datapoint per group.
If 'only_latest_value' is set to true then the 'is_timeseries' parameter is ignored.
Retrieving the Latest Value Only
The 'only_latest_value' parameter allows you to retrieve only the latest value for each group. This can be useful when you only need the most recent value for each room, for example. When set to true, the result will only contain one data point per group for each measurement, rule or unit matching the specified filters.
Specifying a Time Period
The 'from' and 'to' parameters allow you to specify a time period for your query. You can use none, one, or both of these parameters. If you do not specify any, the API will not filter the data based on time.
The time must be specified in ISO 8601 format, for example '2021-01-01T00:00:00.000Z' or '2021-01-01T00:00:00.000+01:00' to include your time zone.
Retrieving Large Amounts of Data
As mentioned before, by default the API will return a maximum of 2,000 records at a time. If you need to retrieve more records, you will need to use the 'limit' and 'offset' parameters to split your query into multiple requests.
The 'limit' parameter defines how many records you want to retrieve, and the 'offset' parameter defines how many records you want to skip.
When splitting a query into multiple requests, make sure that all other parameters in the query remain the same.
For example, the first request would have 'limit' set to 2000 and 'offset' set to 0. The second request would have 'limit' set to 2000 and 'offset' set to 2000. Once the number of records returned is less than the specified 'limit', you have reached the end of your query.
Return data value format
Below is an example of the data returned by the query endpoint. The data is returned in a list of objects, with each object representing a data point.
Looking closely you see that there are multiple fields representing the value of the point: The raw value, 'value' and the aggregated fields 'average_value', 'count_value', 'sum_value', 'min_value' and 'max_value'. Depending on the configuration of the query, some of these fields may be empty. Below are the rules that dictate which fields are populated:
- If "is_latest_value" is set to true, only the "value" field will be populated.
- If "is_timeseries" is set to true and the resolution is not set to "raw", only the aggregated fields will be populated.
- If "is_timeseries" is set to true and the resolution is set to "raw", only the "value" field will be populated.
- If "is_timeseries" is set to false and "is_latest_value" is set to false, only the aggregated fields will be populated.
View the note under Grouping Data to understand when the different "group_*" fields are populated.
Example Query Payloads
Here are a few examples of how you can use the Query API endpoint to retrieve sensor data in Relynk:
Retrieving the Latest Temperature Readings of All Rooms on a Floor
The following query retrieves the latest temperature readings of all rooms on a floor with id 'b5bada34-ae4e-488c-8edc-1e1daa0621ed':
{
"filters": [
{
"filter_on": "asset_id",
"value": [
"b5bada34-ae4e-488c-8edc-1e1daa0621ed" // This is the asset id of the floor
]
},
{
"filter_on": "measurement",
"value": ["Temperature"]
}
],
"group_on": "Room",
"resolution": "1 hour", // This is ignored because only_latest_value is set to true
"is_timeseries": true, // This is ignored because only_latest_value is set to true
"only_latest_value": true
}
Retrieving the Average Humidity of All Sensors in a Building
The following query retrieves the average humidity of all sensors in a building with asset_id of '7f47b79f-539e-401f-9261-12b63c772a78' on January 1st, 2023 between 08:00 and 16:00 in the +01 timezone:
{
"filters": [
{
"filter_on": "asset_id",
"value": [
"7f47b79f-539e-401f-9261-12b63c772a78" // This is the asset id of the building
]
},
{
"filter_on": "measurement",
"value": ["RelativeHumidity"]
}
],
"group_on": "Building",
"resolution": "1 hour", // This is ignored because is_timeseries is set to false
"is_timeseries": false,
"only_latest_value": false,
"to": "2023-01-01T08:00:00.000Z+01:00",
"from": "2023-01-01T16:00:00.000+01:00"
}
Retrieving Room Presence over Time
The following query retrieves the presence of a room with id 'a1f066a4-a336-4937-8bd8-103e034cb2af' over time at a 1 hour resolution:
{
"filters": [
{
"filter_on": "asset_id",
"value": [
"a1f066a4-a336-4937-8bd8-103e034cb2af" // This is the asset id of the room to get presence from
]
},
{
"filter_on": "measurement",
"value": ["Presence"]
}
],
"group_on": "Room",
"resolution": "1 hour",
"is_timeseries": true,
"only_latest_value": false
}
Conclusion
You can use the examples above as a guide to understand how to structure your query payloads to effectively retrieve sensor data using the Query API endpoint in Relynk. Remember to use filters, grouping, and resolution to effectively retrieve the data you need, and use the 'is_timeseries', 'only_latest_value', 'to' and 'from' and 'limit' and 'offset' parameters as appropriate.
View the full Query API Reference here API Reference - Query Endpoint