# Ingesting JSON Data into Datacake API Devices

## Introduction

Sensor readings are a crucial part of many IoT applications, providing valuable data on a wide range of environmental and operational parameters. The Datacake API makes it easy to collect and manage sensor readings from multiple devices, allowing you to integrate them with other applications and services.

To send sensor readings to the Datacake API, you can use a variety of protocols and formats, including JSON. In this example, we demonstrate how to generate sensor readings as a dictionary with a unique `serial_number` field, and how to format these readings into an array of objects that can be sent to the Datacake API.

Additionally, the Datacake API allows for timestamps to be recorded for each reading, which enables you to back-record multiple measurements of the same field in time. In this example, we include timestamps for each reading object in the array, and demonstrate how to modify the decoder function to handle these timestamps.

Overall, the Datacake API provides a flexible and powerful platform for collecting and managing sensor readings from a wide range of devices and applications.

### Video

{% embed url="<https://youtu.be/ZCd5JDX0D34>" %}

## Single Device Data

Let's assume you send the following JSON to a Datacake API device.

```json
{
    "serial_number": "ABC123",
    "temperature": 24.5,
    "humidity": 53.2,
    "pressure": 1013.25,
    "acceleration_x": 0.12,
    "acceleration_y": -0.23,
    "acceleration_z": 1.01,
    "magnetic_field_x": 0.85,
    "magnetic_field_y": -0.92,
    "magnetic_field_z": 0.12,
    "gyroscope_x": -0.02,
    "gyroscope_y": 0.15,
    "gyroscope_z": -0.08,
    "uv_index": 5.2,
    "ambient_light": 132.5
}
```

In this example, the `serial_number` field is a string that uniquely identifies the sensor that produced the readings. The other fields represent different measurements that the sensor might be capable of taking, such as temperature, humidity, pressure, acceleration, magnetic field, gyroscope, UV index, and ambient light. The values of these fields are floating-point numbers that represent the actual readings taken by the sensor.

### Payload Decoder

Here's an example of a decoder function that parses the sensor readings from the payload of a Datacake API device request and returns them as an array of objects with the required format:

```javascript
function Decoder(request) {
    var payload = JSON.parse(request.body);
    var device = payload.serial_number;
    var readings = [];
    
    for (var field in payload) {
        if (field !== "serial_number") {
            readings.push({
                field: field,
                value: payload[field],
                device: device
            });
        }
    }
    
    return readings;
}
```

Simply paste the above decoder into the decoder section of your API device on Datacake.

## Multiple Devices in Single Payload

In case you want to embed the data of multiple devices into a single payload, you simply have to adapt the payload decoder.

```javascript
function Decoder(request) {
    var payload = JSON.parse(request.body);
    var readings = [];
    
    for (var i = 0; i < payload.length; i++) {
        var device = payload[i].serial_number;
        for (var field in payload[i]) {
            if (field !== "serial_number") {
                readings.push({
                    field: field,
                    value: payload[i][field],
                    device: device
                });
            }
        }
    }
    
    return readings;
}
```

n this example, the `Decoder` function receives a `request` object that contains an array of JSON objects, each representing the sensor readings from a different device. The `payload` variable is assigned the parsed JSON array from the request body, and the `readings` array is initialized.

The function then iterates over the devices in the payload using a `for` loop, and for each device, it extracts the `serial_number` and assigns it to the `device` variable. It then iterates over the fields in the device's payload using another `for` loop, skipping the `serial_number` field. For each field, it creates an object with the required `field`, `value`, and `device` properties, and adds it to the `readings` array.

Finally, the function returns the `readings` array, which contains an object for each sensor reading with the required format of `{field: field, value: value, device:device}`.

And here's an example of a fake data array containing readings from two devices:

```json
[
    {
        "serial_number": "ABC123",
        "temperature": 24.5,
        "humidity": 53.2,
        "pressure": 1013.25
    },
    {
        "serial_number": "DEF456",
        "temperature": 22.1,
        "humidity": 60.7,
        "pressure": 1012.85
    }
]
```

## Providing Timestamps

Datacake API devices allow you to backrecord historical data from both single and multiple devices (yes that is super awesome!). See the following example.

### Demo Data

```json
// Example fake data array containing readings from two devices with timestamps
var readings = [
    {
        "serial_number": "ABC123",
        "temperature": [
            { value: 24.5, timestamp: 1648909263 },
            { value: 23.8, timestamp: 1648909273 },
            { value: 22.9, timestamp: 1648909283 }
        ],
        "humidity": [
            { value: 53.2, timestamp: 1648909263 },
            { value: 52.5, timestamp: 1648909273 },
            { value: 51.8, timestamp: 1648909283 }
        ],
        "pressure": [
            { value: 1013.25, timestamp: 1648909263 },
            { value: 1013.12, timestamp: 1648909273 },
            { value: 1012.98, timestamp: 1648909283 }
        ]
    },
    {
        "serial_number": "DEF456",
        "temperature": [
            { value: 22.1, timestamp: 1648909263 },
            { value: 22.9, timestamp: 1648909273 },
            { value: 23.5, timestamp: 1648909283 }
        ],
        "humidity": [
            { value: 60.7, timestamp: 1648909263 },
            { value: 59.8, timestamp: 1648909273 },
            { value: 58.9, timestamp: 1648909283 }
        ],
        "pressure": [
            { value: 1012.85, timestamp: 1648909263 },
            { value: 1013.01, timestamp: 1648909273 },
            { value: 1013.18, timestamp: 1648909283 }
        ]
    }
];
```

### Decoder

Use the following decoder to decode the above data. Simply paste into Datacake API device decoder section.

```javascript
// Example decoder function that includes timestamps for each reading
function Decoder(request) {
    var payload = JSON.parse(request.body);
    var readings = [];
    
    for (var i = 0; i < payload.length; i++) {
        var device = payload[i].serial_number;
        for (var field in payload[i]) {
            if (field !== "serial_number") {
                var values = payload[i][field];
                for (var j = 0; j < values.length; j++) {
                    var reading = {
                        field: field,
                        value: values[j].value,
                        device: device,
                        timestamp: values[j].timestamp
                    };
                    readings.push(reading);
                }
            }
        }
    }
    
    return readings;
}
```

In this example, the `readings` array contains objects for each device with each field containing an array of readings that includes both a `value` and a `timestamp`. The `Decoder` function now loops over each field in the payload, extracts the `values` array, and loops over each reading in the array. For each reading, it creates an object with the required `field`, `value`, `device`, and `timestamp` properties, and adds it to the `readings` array.

Note that the `timestamp` property is now included in each reading object, and represents the Unix timestamp in seconds when the reading was taken.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.datacake.de/guides/ingesting-json-data-into-datacake-api-devices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
