Readings¶
Reading Data Structure¶
A reading is a parsed and human-readable unit of sensor data generated by a device, sent in a packet.
Packets can be accessed using the API, or pushed by a websocket.
In responses, a reading looks like this:
{
"parser_id": "cee40cb2-f58c-4ca8-ae91-4ae76cba5119",
"packet_id": "7ba0beee-1ea5-4a4b-b20c-75c2706c9710",
"measured_at": "2017-08-02T09:11:04.910127Z",
"location": null,
"inserted_at": "2017-08-02T09:11:04.918087Z",
"id": "07c04413-940b-4ee6-be99-da72a0321e25",
"device_id": "43b5dca3-e7d9-4028-9309-c26ac0c08721",
"data": {
"foo": 96,
"baz": 8,
"bar": 35
}
}
Key | Example | Description |
---|---|---|
id | 3e097a97-e504-4b4b-8182-ae148f2109f3 | Unique reading ID (UUID4) |
data | {"foo": 96, "baz": 8, "bar": 35} | JSON object that represents the parsed data |
inserted_at | 2017-07-31T12:15:18.289981Z | When did the reading get inserted into the database |
measured_at | 2017-07-31T12:15:18.289981Z | When did the measurement happen (may be provided by the device in the payload, infered from the receive time or simply be same as receive time) |
parser_id | cee40cb2-f58c-4ca8-ae91-4ae76cba5119 | Reference to a parser which parsed the payload into the data |
device_id | 50e032fb-964f-440d-9b9a-47870667373c | Reference to the device this reading belongs to |
packet_id | 50e032fb-964f-440d-9b9a-47870667373c | Reference to the packet this reading belongs to |
location | {"location": {"type": "Point", "coordinates": [40.3684324046728, 42.221249216157474]}} | GeoJSON point of the location where the reading was taken |
List Readings¶
There are different ways to retrieve readings with the API:
- by device ID
GET /api/v1/devices/:id/readings
- by device slug
GET /api/v1/devices/:slug/readings
- by selector, for example
GET /api/v1/devices/by-eui/:eui/readings
- by folder
GET /api/v1/tags/:id_or_slug/readings
(parameters are denoted with a colon (:
), which does not appear in the final API request)
Additionally, a streaming variant of all these endpoints is available, simply append /stream
to any of these.
Query parameters¶
For all of the above endpoints, the available query parameters are the same:
Query Parameter | Description |
---|---|
auth String* | API Key or JWT |
retrieve_after UUID | To go to the next page, pass the ID of the last reading from the result list here. Read more about pagination |
sort Field | Field to sort the readings by (default measured_at , inserted_at is also available) |
sort_direction asc or desc | Switch the sort direction (default desc ) |
limit Integer 1-100 | Control how many readings are loaded per page (default 10 ) when using streaming endpoints, the amount of readings is not limited by default |
before ISO8601 | Only show readings measured before this date |
after ISO8601 | Only show readings measured after this date |
filter AbacusSql | Expression that filters the readings. The root schema of the filter is a reading. |
simple filters | use filters like inserted_before=2020 |
* = required parameter
Examples¶
/api/v1/devices/demo/readings?sort=inserted_at&retrieve_after=:uuid&auth=46cb688e2c0b468e26e914235d4b73ea
Paginating over readings by insertion date is possible by using the sort=inserted_at
query parameter.
-
/api/v1/devices/by-eui/DEADAFFE00001111/readings?inserted_after=2020-11-11&auth=46cb688e2c0b468e26e914235d4b73ea
Filtering for the
inserted_at
field can be useful if you need to synchronize readings with your applications database and the readings are dated back by the parser.
Notes on inserted_at
vs. measured_at
¶
Since the time of measurement may not be the time ELEMENT IoT will receive a packet and parse it to a reading, please take the following guidelines into account.
inserted_at
is always the time a reading was stored by ELEMENT IoT into its database. measured_at
is the time ELEMENT deems the reading to be measured at by the end-device.
There are different situations that will influence how measured_at
and inserted_at
differ or not:
- If the device is not signaling a measurement time that differs from the time the packet is send and there is no implicit rule on how to calculate a measurement time from the time of reception, then
measured_at
will be the time when ELEMENT receives and stores the measurement. Thusmeasured_at
andinserted_at
will be virtually the same - maybe differing be a few fractions of a second due to technical reasons. - If the device is signaling a
measured_at
time, this one will be used and may be well adhead ofinserted_at
time. - If a reparsing of packets is triggered any time later by a user, then
inserted_at
is the time the new readings isinserted_at
(since reparsing means all readings of the affected device are deleted and new ones are created). Thusinserted_at
may differ significantly frommeasured_at
.
So if an external system is querying for readings using ELEMENTs API for a given timeframe at a given time, it may be that readings with a measured_at
belonging into the timeframe are not yet inserted and thus cannot be included in the results yet, but will be at some later time. To really make sure that all readings are retreived considering above point, it may be best to either filter (using e.g. before
and after
parameters) on inserted_at
or retrieve a timeframe for measured_at
sufficently later (depending the timespan queryied devices take from measurement to transmission).
Reparsing will delete readings originating from the previous parsing. External systems should potentially no longer keep these readings. So a user triggering a reparse - it can't be triggered any other way - should consider this and take care of necessary steps in other systems.