Accessing Data

There are three ways of accessing your data in the BACE system:

  1. The Fastest: the data-downsampled endpoint Use this endpoint when you want to poll data with fast response times, e.g. for graphing purposes.

  2. The Easiest: webhooks Use a webhook when you want retrieve all raw data continuously.

  3. The Most Precise: the data endpoint Use this endpoint for a one-time export of raw data over a certain time period.

The data-downsampled and data endpoints are explained in this section. Note that a separate section is dedicated to webhooks.

BACE Webhooks

Accessing data, the fast way

Down-sampled data is a great way of improving performance of retrieving data. Raw data in the BACE system is aggregated per minute, hour and day for this reason. In general we recommend the data-downsampledendpoint for accessing data. This endpoint is the most high performing endpoint for data polling. It is excellent for graphing and visualisation purposes.

A list of all downsampled endpoints accessible by user can be retrieved as follows:

List downsampled data

GET https://dashboard.bace-iot.com/api/v2/data-downsampled/index

The response will be a paginated list of all downsampled endpoints accessible by the users.

"items": [
        {
            "id_container_data_latest": "112e51e6-...",
            "id_group": "b7624b4d-...",
            "datatype": 2073,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647907200,
            "min_val": 0,
            "max_val": 0,
            "avg_val": 0,
            "count_val": 263
        },
        {
            "id_container_data_latest": "1aec07ea-...",
            "id_group": "b7624b4d-...",
            "datatype": 2070,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647907200,
            "min_val": 0,
            "max_val": 59.5999984741,
            "avg_val": 7.93155873229467,
            "count_val": 263
        },
        {
            "id_container_data_latest": "2f333ae8-...",
            "id_group": "b7624b4d-...",
            "datatype": 2101,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 43806,
            "max_val": 57005,
            "avg_val": 52856.7428571429,
            "count_val": 35
        },
        {
            "id_container_data_latest": "490beb6b-...",
            "id_group": "b7624b4d-...",
            "datatype": 5003,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 0,
            "max_val": 27,
            "avg_val": 6.84732824427481,
            "count_val": 262
        },
        {
            "id_container_data_latest": "858424d7-...",
            "id_group": "b7624b4d-...",
            "datatype": 2071,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647907200,
            "min_val": 59.5999984741,
            "max_val": 59.5999984741,
            "avg_val": 59.5999984741001,
            "count_val": 263
        },
        {
            "id_container_data_latest": "8faac4b0-...",
            "id_group": "b7624b4d-...",
            "datatype": 5000,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 27.7362060547,
            "max_val": 30.3244018555,
            "avg_val": 29.0922662866034,
            "count_val": 262
        },
        {
            "id_container_data_latest": "acb5d7fe-...",
            "id_group": "b7624b4d-...",
            "datatype": 2072,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647907200,
            "min_val": 390,
            "max_val": 390.6000061035,
            "avg_val": 390.079848720998,
            "count_val": 263
        },
        {
            "id_container_data_latest": "b8c1c262-...",
            "id_group": "b7624b4d-...",
            "datatype": 2100,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 0,
            "max_val": 57005,
            "avg_val": 52372.1140065147,
            "count_val": 307
        },
        {
            "id_container_data_latest": "c8bb58e9-...",
            "id_group": "b7624b4d-...",
            "datatype": 2102,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 43806,
            "max_val": 47836,
            "avg_val": 45072.5714285714,
            "count_val": 35
        },
        {
            "id_container_data_latest": "f54d5550-...",
            "id_group": "b7624b4d-...",
            "datatype": 5001,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1647993600,
            "min_val": 24.7131347656,
            "max_val": 33.5266113281,
            "avg_val": 27.4022924991168,
            "count_val": 262
        }
    ],
    "_links": {
        "self": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data-downsampled?filter%5Bid_group%5D=b7624b4d-...&page=1"
        },
        "first": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data-downsampled?filter%5Bid_group%5D=b7624b4d-...&page=1"
        },
        "last": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data-downsampled?filter%5Bid_group%5D=b7624b4d-...&page=1"
        }
    },
    "_meta": {
        "totalCount": 10,
        "pageCount": 1,
        "currentPage": 1,
        "perPage": 500
    }

By default you will receive aggregated data per day from the device. In order to get more precise data we should request a smaller chunks of time, like so:

Access downsampled data

GET https://dashboard.bace-iot.com/api/v2/data-downsampled

Filters are recommend to access downsampled data. In this example, a time interval and group filter is set.

Query Parameters

Name
Type
Description

filter[id_group]

4c1c81ca-...

filter[timestamp_seconds][gt]

1652691600

From timestamp

filter[timestamp_seconds][lt]

1652778001

To timestamp

sort

-timestamp_seconds

Sort on timestamp

{
    "items": [
        {
            "id_container_data_latest": "c1dafb46-...",
            "id_group": "4c1c81ca-...",
            "datatype": 5205,
            "source_device": "6b88b4df-...",
            "timestamp_seconds": 1652706000,
            "min_val": 4.106001,
            "max_val": 4.21,
            "avg_val": 4.12140803703704,
            "count_val": 27
        },
        {
            "id_container_data_latest": "f2d754ba-...",
            "id_group": "4c1c81ca-...",
            "datatype": 6000,
            "source_device": "8329650b-...",
            "timestamp_seconds": 1652706000,
            "min_val": 1,
            "max_val": 1,
            "avg_val": 1,
            "count_val": 27
        },
        {
            "id_container_data_latest": "8e00087e-...",
            "id_group": "4c1c81ca-...",
            "datatype": 6000,
            "source_device": "d6a18bf2-...",
            "timestamp_seconds": 1652702400,
            "min_val": 100,
            "max_val": 103,
            "avg_val": 101.5,
            "count_val": 2
        },
        {
            "id_container_data_latest": "c1dafb46-...",
            "id_group": "4c1c81ca-...",
            "datatype": 5205,
            "source_device": "6b88b4df-...",
            "timestamp_seconds": 1652702400,
            "min_val": 4.090001,
            "max_val": 4.126667,
            "avg_val": 4.10807645454545,
            "count_val": 55
        },
        {
            "id_container_data_latest": "f2d754ba-...",
            "id_group": "4c1c81ca-...",
            "datatype": 6000,
            "source_device": "8329650b-...",
            "timestamp_seconds": 1652702400,
            "min_val": 1,
            "max_val": 1,
            "avg_val": 1,
            "count_val": 5
        }
    ],
    "_links": {
        "self": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_group%5D=4c1c81ca-1ef9-47ac-9c03-97060db9d021&filter%5Btimestamp_seconds%5D%5Bgt%5D=1652691600&filter%5Btimestamp_seconds%5D%5Blt%5D=1652778001&sort=-timestamp_seconds&page=1"
        },
        "first": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_group%5D=4c1c81ca-1ef9-47ac-9c03-97060db9d021&filter%5Btimestamp_seconds%5D%5Bgt%5D=1652691600&filter%5Btimestamp_seconds%5D%5Blt%5D=1652778001&sort=-timestamp_seconds&page=1"
        },
        "last": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_group%5D=4c1c81ca-1ef9-47ac-9c03-97060db9d021&filter%5Btimestamp_seconds%5D%5Bgt%5D=1652691600&filter%5Btimestamp_seconds%5D%5Blt%5D=1652778001&sort=-timestamp_seconds&page=1"
        }
    },
    "_meta": {
        "totalCount": 5,
        "pageCount": 1,
        "currentPage": 1,
        "perPage": 500
    }
}

Because the time interval the data was requested over was more than a day in this case, the endpoint responded with hour aggregates. The precision of the data depends, i.e. the aggregation period is determined by the time interval data is requested over. The smaller the time interval, the more precise the data will be. The logic for this is shown in the schematic below.

In order to reduce the resource load on our data storage, a maximum of 100 different datasets can be fetched in one request. A dataset is a unique combination of 1 group, 1 device and 1 datatype. For example, if you have 2 groups with 2 devices each reporting 2 datatypes, that’s 8 distinct datasets. This limitation can be avoided by applying further filtering, explained in the next paragraph.

Filtering

This limitation is avoided by querying smaller chunks of time, or fewer datasets.

With filters you determine what data you want to retrieve. As explained in the previous section the most common onces are id_group or source_device. The table below provides comprehensive overview of parameters that can be applied:

Field
Description

id_container_data_latest

UUID which describes combination of Group, Physical Device and Datatype

id_group

UUID of Group

datatype

Datatype of stored data

source_device

UUID of Physical Device, BACE Cloud have received data from

timestamp_seconds

Timestamp in seconds

min_val

Minimal value

max_val

Maximal value

avg_val

Average value

count_val

Count of downsampled samples

You can also request data between two timestamps to get more data, with a higher resolution.

For example you would be interested in getting temperature data.

To get more detailed information about datatype meaning, you should make GET request, to the Group endpoint with the same ID group, you have used to get data, and expand response on dataTypes

GET https://dashboard.bace-iot.com/api/v2/group/b7624b4d-...?expand=dataTypes
Response:
{
  "id": "b7624b4d-...",
  "id_group": "b7624b4d-...",
  "label": "BacePlus-...",
  "type": "5003",
  "type_label": "Loose Device",
  "subtype": "...",
  "id_country": null,
  "created_at": 1647963043,
  "dataTypes": [
      {
          "datatype": 2070,
          "label": "Datatype 2070",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2071,
          "label": "Datatype 2071",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2072,
          "label": "Datatype 2072",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2073,
          "label": "Datatype 2073",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2100,
          "label": "Modbus Parameter 2100",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2101,
          "label": "Modbus Parameter 2101",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 2102,
          "label": "Modbus Parameter 2102",
          "unit": "",
          "precision": 1
      },
      {
          "datatype": 5000,
          "label": "Temperature",
          "unit": "°C",
          "precision": 1
      },
      {
          "datatype": 5001,
          "label": "Relative Humidity",
          "unit": "%",
          "precision": 1
      },
      {
          "datatype": 5003,
          "label": "Presence",
          "unit": "",
          "precision": 0
      }
  ],
  "_links": {
      "self": {
          "href": "/api/v2/group/b7624b4d-..."
      },
      "index": {
          "href": "/api/v2/group/index"
      },
      "data": {
          "href": "/api/v2/data?filter[id_group]=b7624b4d-..."
      },
      "downsampled_data": {
          "href": "/api/v2/data-downsampled?filter[id_group]=b7624b4d-..."
      },
      "raw_data": {
          "href": "/api/v2/data/index?filter[id_group]=b7624b4d-..."
      }
  }
}

In the response you will get basic information about this group, and also information about all datatypes related to this group.

For example we want to get Temperature in °C from Group response, we can see that it is datatype 5000.

{
    "datatype": 5000,
    "label": "Temperature",
    "unit": "°C",
    "precision": 1
}

Now when we know, that Temperature has datatype 5000, we can go back to Downsampled data endpoint and find id_container_data_latest, matching our Temperature datatype

{
    "id_container_data_latest": "8faac4b0-...,
    "id_group": "b7624b4d-...",
    "datatype": 5000,
    "source_device": "007ed6e0-...",
    "timestamp_seconds": 1647993600,
    "min_val": 27.7362060547,
    "max_val": 30.3244018555,
    "avg_val": 29.0922662866034,
    "count_val": 262
}

Now we can request just Temperature in °C data. We will make our request more specific. In our response from data_downsampled endpoint we can see "timestamp_seconds": 1647993600 - Wed Mar 23 2022 01:00:00 GMT+0100 (Central European Standard Time). Then we will try to request data for 24 hours from this timestamp.

Wed Mar 23 2022 01:00:00 GMT+0100 (Central European Standard Time) - Thu Mar 24 2022 01:00:00 GMT+0100 (Central European Standard Time)

We will make GET request to the same endpoint, but we will add two more filters and will sort received data on a timestamp_seconds - descending.

GET https://dashboard.bace-iot.com/api/v2/data-downsampled?filter[id_container_data_latest]=8faac4b0-…&filter[timestamp_seconds][gt]=1647993600&filter[timestamp_seconds][lt]=1648080000&sort=-timestamp_seconds

Response:

{
    "items": [
        {
            "id_container_data_latest": "8faac4b0-...",
            "id_group": "b7624b4d-...",
            "datatype": 5000,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1648051140,
            "min_val": 29.9517822266,
            "max_val": 30.022277832,
            "avg_val": 29.9870300293,
            "count_val": 2
        },
        {
            "id_container_data_latest": "8faac4b0-...",
            "id_group": "b7624b4d-...",
            "datatype": 5000,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1648051080,
            "min_val": 29.9819946289,
            "max_val": 30.022277832,
            "avg_val": 30.00213623045,
            "count_val": 2
        },
        {
            "id_container_data_latest": "8faac4b0-...",
            "id_group": "b7624b4d-...",
            "datatype": 5000,
            "source_device": "007ed6e0-...",
            "timestamp_seconds": 1648051020,
            "min_val": 29.9517822266,
            "max_val": 30.022277832,
            "avg_val": 29.9870300293,
            "count_val": 2
        },
        ...
    ],
    "_links": {
        "self": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1647993600&filter%5Btimestamp_seconds%5D%5Blt%5D=1648080000&sort=-timestamp_seconds&page=1"
        },
        "first": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1647993600&filter%5Btimestamp_seconds%5D%5Blt%5D=1648080000&sort=-timestamp_seconds&page=1"
        },
        "last": {
            "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1647993600&filter%5Btimestamp_seconds%5D%5Blt%5D=1648080000&sort=-timestamp_seconds&page=1"
        }
    },
    "_meta": {
        "totalCount": 201,
        "pageCount": 1,
js        "currentPage": 1,
        "perPage": 500
    }
}

Now we can find more data in the response, with 1 value per minute. But we can still see that there is some data in between, because "count_val": 2.

So to get raw data we can make last request.

GET https://dashboard.bace-iot.com/api/v2/data-downsampled?filter[id_container_data_latest]=8faac4b0-a971-47c6-bd16-c80b2ef99299&filter[timestamp_seconds][gt]=1648051080&filter[timestamp_seconds][lt]=1648051140&sort=-timestamp_seconds

In this case we are requesting data between 1648051080 - Wed Mar 23 2022 16:58:00 GMT+0100 (Central European Standard Time) and 1648051140 - Wed Mar 23 2022 16:59:00 GMT+0100 (Central European Standard Time)

Response:

{
  "items": [
      {
          "id_container_data_latest": "8faac4b0-...",
          "id_group": "b7624b4d-...",
          "datatype": 5000,
          "source_device": "007ed6e0-...",
          "timestamp_seconds": 1648051122,
          "min_val": "30.022277832",
          "max_val": "30.022277832",
          "avg_val": "30.022277832",
          "count_val": 1
      },
      {
          "id_container_data_latest": "8faac4b0-...",
          "id_group": "b7624b4d-...",
          "datatype": 5000,
          "source_device": "007ed6e0-...",
          "timestamp_seconds": 1648051090,
          "min_val": "29.9819946289",
          "max_val": "29.9819946289",
          "avg_val": "29.9819946289",
          "count_val": 1
      }
  ],
  "_links": {
      "self": {
          "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1648051080&filter%5Btimestamp_seconds%5D%5Blt%5D=1648051140&sort=-timestamp_seconds&page=1"
      },
      "first": {
          "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1648051080&filter%5Btimestamp_seconds%5D%5Blt%5D=1648051140&sort=-timestamp_seconds&page=1"
      },
      "last": {
          "href": "https://dashboard.bace-iot.com/api/v2/data-downsampled?filter%5Bid_container_data_latest%5D=8faac4b0-...&filter%5Btimestamp_seconds%5D%5Bgt%5D=1648051080&filter%5Btimestamp_seconds%5D%5Blt%5D=1648051140&sort=-timestamp_seconds&page=1"
      }
  },
  "_meta": {
      "totalCount": 2,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 500
  }
}

In the response we will find raw data points.

How to know, that it is raw data:

  • We can find, that "count_val": 1 It means there is no more data in between two timestamps

  • We can also convert timestamp, for example: 1648051122, to datetime: Wed Mar 23 2022 16:58:42 GMT+0100 (Central European Standard Time). And we will see, that time is not rounded 16:58:42

  • Minimal, maximal & average values are equal

Conclusion

So to get data from aggregated data endpoint we should follow reverse logic.

We start from getting 1 value per day. This is what downsampled_data endpoint returns without timestamp_seconds filters or if time interval is greater than 3 weeks.

If you want to get more accurate data, we are able to request hourly aggregated data, by having our request interval less then 3 weeks and greater than 1 day. It should return 1 value per hour.

Then we can make request and keep interval less than 1 day and greater than 1 hour to get data aggregated to 1 value per minute.

To get raw data, we should make request, where requested interval would be less than 1 hour - it should return raw data

Accessing raw data

The below example shows how the data endpoint can be called with a filter on id_group to access that groups data:

Access group data

GET https://dashboard.bace-iot.com/api/v2/data?filter[id_group]=0fcf513b-...

Response will be a paginated list of datapoints that are available in the group.

{
    "items": [
        {
            "id_container_data_latest": "17833fcc-...",
            "id_group": "0fcf513b-...",
            "datatype": 2105,
            "source_device": "40f0462c-...",
            "timestamp_seconds": 1628774057,
            "microseconds": 965000,
            "value": 50
        },
        {
            "id_container_data_latest": "17833fcc-...",
            "id_group": "0fcf513b-...",
            "datatype": 2106,
            "source_device": "40f0462c-...",
            "timestamp_seconds": 1628774064,
            "microseconds": 275000,
            "value": 100
        },
        {
            "id_container_data_latest": "17833fcc-...",
            "id_group": "0fcf513b-...",
            "datatype": 2107,
            "source_device": "40f0462c-...",
            "timestamp_seconds": 1628774070,
            "microseconds": 575000,
            "value": 0
        }
    ],
    "_links": {
        "self": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data/index?filter%5Bid_group%5D=0fcf513b-..."
        },
        "first": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data/index?filter%5Bid_group%5D=0fcf513b-..."
        },
        "last": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data/index?filter%5Bid_group%5D=0fcf513b-..."
        },
        "next": {
            "href": "https://evalan-dev-bace-webapp.azurewebsites.net/api/v2/data/index?filter%5Bid_group%5D=30fcf513b-...&page=2"
        }
    },
    "_meta": {
        "totalCount": 3,
        "pageCount": 3,
        "currentPage": 1,
        "perPage": 500
    }
}

From the response we see that this group has three data points from three different datatypes available. If more than 500 datapoints are available in the group the response will be paginated with latest data on top. Please refer to the Advanced Features section to learn about browsing through pages.

Note that both the data endpoint requires you to set a filter. Forgetting the filter will result in an error.

Last updated