# API Examples

## Logging data and returning data

All requests require the `X-API-KEY` header.

```
X-API-KEY: your-key-here
```

Replace `<root>` with the name of the `FLASK_ROOT` from your secrets file.

Replace `https://your-server` with your server address and port.

---

## POST `/<root>` — Log sensor data

### Single sensor

```python
import requests

response = requests.post(
    "https://your-server/<root>",
    headers={"X-API-KEY": "your-key-here"},
    json={
        "inator": "TempSensor01",
        "temperature": 23.5
    }
)
```

**Response `200`**
```json
{
    "message": "Data received",
    "data": {
        "timestamp": 1234567890,
        "temperature": 23.5
    }
}
```

---

### Multiple sensors

```python
response = requests.post(
    "https://your-server/<root>",
    headers={"X-API-KEY": "your-key-here"},
    json={
        "inator": "WeatherStation01",
        "temperature": 23.5,
        "humidity": 61.2,
        "pressure": 1013.4
    }
)
```

**Response `200`**
```json
{
    "message": "Data received",
    "data": {
        "timestamp": 1234567890,
        "temperature": 23.5,
        "humidity": 61.2,
        "pressure": 1013.4
    }
}
```

---

## GET `/<root>/get` — Query logged data

### All rows for an inator

```python
response = requests.get(
    "https://your-server/<root>/get",
    headers={"X-API-KEY": "your-key-here"},
    params={
        "inator": "TempSensor01"
    }
)
```

**Response `200`**
```json
{
    "data": [
        {"id": 1, "timestamp": 1234567890, "id_1": 23.5},
        {"id": 2, "timestamp": 1234567891, "id_1": 24.1}
    ],
    "count": 2
}
```

---

### Filter by timestamp

```python
response = requests.get(
    "https://your-server/<root>/get",
    headers={"X-API-KEY": "your-key-here"},
    params={
        "inator": "TempSensor01",
        "timestamp": 1234567890
    }
)
```

---

### Filter by multiple columns

```python
response = requests.get(
    "https://your-server/<root>/get",
    headers={"X-API-KEY": "your-key-here"},
    params={
        "inator": "WeatherStation01",
        "timestamp": 1234567890,
        "id_1": 23
    }
)
```

> **Note:** Column filters use the internal log table column names (`id_1`, `id_2`, etc.)
> rather than sensor names. The mapping of sensor name to column id can be found
> in the device details table.

---

## Error Responses

| Status | Reason                                      |
|--------|---------------------------------------------|
| `400`  | Missing or invalid JSON / missing `inator` field / invalid column |
| `401`  | Missing or incorrect API key                |
| `404`  | Inator not found                            |
| `409`  | No database configured                      |
| `418`  | Data received but no logging set up         |

### Examples

**`401` — Missing API key**
```python
response = requests.post(
    "https://your-server/<root>",
    json={"inator": "TempSensor01", "temperature": 23.5}
)
# {"error": "Unauthorized"}
```

**`404` — Unknown inator**
```python
response = requests.get(
    "https://your-server/<root>/get",
    headers={"X-API-KEY": "your-key-here"},
    params={"inator": "UnknownDevice"}
)
# {"error": "Inator 'UnknownDevice' not found"}
```

**`400` — Invalid column**
```python
response = requests.get(
    "https://your-server/<root>/get",
    headers={"X-API-KEY": "your-key-here"},
    params={"inator": "TempSensor01", "badcol": "123"}
)
# {"error": "Invalid columns: ['badcol']"}
```

---

## POST `/api/devices` — Register devices

Register one or more devices (with their sensors).

### Request Body

```json
{
  "devices": [
    {
      "device_name": "Weather Station Alpha",
      "device_guid": "550e8400-e29b-41d4-a716-446655440000",
      "num_sensors": 2,
      "device_info": "Outdoor weather monitoring unit",
      "device_type": "Environmental",
      "device_location": "Rooftop - Building A",
      "device_active": 1,
      "connection": "MQTT",
      "sensors": [
        {
          "sens_name": "Temperature Sensor",
          "measures": "Temperature",
          "returns": "float",
          "calib": "factory",
          "range": "-40 to 85 °C",
          "info": "DS18B20 digital thermometer",
          "comments": "Calibrated 2024-01-15"
        },
        {
          "sens_name": "Humidity Sensor",
          "measures": "Relative Humidity",
          "returns": "float",
          "calib": "factory",
          "range": "0 to 100 %RH",
          "info": "DHT22 humidity sensor",
          "comments": "Check filter quarterly"
        }
      ]
    }
  ]
}
```

### Fields Reference

#### Device Fields

| Field             | Type    | Required | Description                               |
|-------------------|---------|----------|-------------------------------------------|
| `device_name`     | string  | ✅        | Human-readable name for the device        |
| `device_guid`     | string  | ✅        | Unique identifier (UUID recommended)      |
| `num_sensors`     | integer | ✅        | Number of sensors attached to this device |
| `device_info`     | string  | ✅        | Description or notes about the device     |
| `device_type`     | string  | ✅        | Category or type of device                |
| `device_location` | string  | ✅        | Physical location of the device           |
| `device_active`   | integer | ✅        | `1` = active, `0` = inactive              |
| `connection`      | string  | ✅        | One of: `Serial`, `MQTT`, `http`, `Other` |
| `sensors`         | array   | ✅        | List of sensor objects (see below)        |

#### Sensor Fields

| Field       | Type   | Required | Description                                   |
|-------------|--------|----------|-----------------------------------------------|
| `sens_name` | string | ✅        | Name of the sensor                            |
| `measures`  | string | ✅        | What the sensor measures (e.g. `Temperature`) |
| `returns`   | string | ✅        | Data type returned (e.g. `float`, `int`)      |
| `calib`     | string | ✅        | Calibration method or status                  |
| `range`     | string | ✅        | Operating range (e.g. `0 to 100 %RH`)         |
| `info`      | string | ✅        | Additional technical info or model number     |
| `comments`  | string | ✅        | Free-text notes or maintenance comments       |

### Example

```python
import requests

response = requests.post(
    "https://your-server/api/devices",
    headers={"X-API-KEY": "your-key-here"},
    json={
        "devices": [
            {
                "device_name": "Weather Station Alpha",
                "device_guid": "550e8400-e29b-41d4-a716-446655440000",
                "num_sensors": 1,
                "device_info": "Outdoor unit",
                "device_type": "Environmental",
                "device_location": "Rooftop",
                "device_active": 1,
                "connection": "MQTT",
                "sensors": [
                    {
                        "sens_name": "Temperature Sensor",
                        "measures": "Temperature",
                        "returns": "float",
                        "calib": "factory",
                        "range": "-40 to 85 °C",
                        "info": "DS18B20",
                        "comments": "Calibrated 2024-01-15"
                    }
                ]
            }
        ]
    }
)
```

### Responses

| Status | Meaning                                          |
|--------|--------------------------------------------------|
| `200`  | Devices registered successfully                  |
| `400`  | Invalid or missing JSON body                     |
| `401`  | Missing or incorrect API key                     |
| `409`  | Database not configured on the server            |
| `422`  | Validation error — check your device/sensor fields |
| `500`  | Server-side database error                       |

**Response `200`**
```json
{
  "message": "Devices registered",
  "data": {
    "devices": [ ... ]
  }
}
```

**Response `422`**
```json
{
  "error": "Description of what failed validation"
}
```

> **Note:** You can register multiple devices in a single request by adding more objects to the `devices` array. All sensor fields are required — empty strings are acceptable if the value is not yet known.