# openSenseMap

> Read live and past readings from openSenseMap's community sensor stations: find stations near a place, in an area or a group, read a station's latest temperature, humidity, fine dust and other values, pull a sensor's history and summarise readings across an area. No account or API key is needed.

App · 12 actions. Web page: https://docs.lodol.com/docs/integrations/opensensemap

## Actions

### Find stations in a group

Find the stations their owners tagged with a group, such as a school, a university or a city project, most recently reporting first.

**Inputs**

- Group (`group`, text, required): The group to list. Pick one or type it exactly as stations are tagged, for example ifgi.
- Placement (`exposures`, list): Only stations placed like this. Choose Outdoors for weather and air quality. Leave empty for every station. One or more of: `outdoor` (Outdoors), `indoor` (Indoors), `mobile` (On the move (bike, car, bus)), `unknown` (Not stated).
- Measures (`phenomenon`, text): Only stations with a sensor for this. Leave empty for every station. Stations name their sensors themselves, mostly in German, so each choice shows the name it matches in brackets. One of: `Temperatur` (Temperature (Temperatur)), `rel. Luftfeuchte` (Relative humidity (rel. Luftfeuchte)), `Luftdruck` (Air pressure (Luftdruck)), `PM10` (Fine dust PM10), `PM2.5` (Fine dust PM2.5), `PM1` (Fine dust PM1), `PM4` (Fine dust PM4), `Beleuchtungsstärke` (Light level (Beleuchtungsstärke)), `UV-Intensität` (UV intensity (UV-Intensität)), `Lautstärke` (Noise level (Lautstärke)), and 4 more.
- Reported from (`reported_from`, date and time): Only stations that sent a reading at or after this moment. Use it to skip stations that have gone quiet. Leave empty for every station.
- Reported until (`reported_until`, date and time): With 'Reported from': the end of that period. Leave empty for up to now.
- How many stations (`limit`, number): How many stations to return (1-500). The total says how many matched. From 1 to 500. Default: `25`.

**Outputs**

- `has_more` (true/false): Whether more matched than were returned
- `stations` (list): The matching stations, most recently reporting first
- `total` (number): How many matched in total

**Example output**

```json
{
  "has_more": true,
  "stations": [
    {
      "created_at": "2021-08-02T12:03:49.808Z",
      "exposure": "outdoor",
      "group_tags": [
        "ifgi"
      ],
      "height_m": null,
      "id": "5a0c347b9fd3c2001111b701",
      "last_reported_at": "2026-10-16T00:16:29.992Z",
      "latitude": 51.962788,
      "link": "https://opensensemap.org/explore/5a0c347b9fd3c2001111b701",
      "longitude": 7.631133,
      "model": "homeV2Lora",
      "name": "VennheideBox",
      "sensors": [
        {
          "id": "6107df25c4aab8001b94e04a",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 18.2,
          "phenomenon": "Temperatur",
          "sensor_type": "HDC1080",
          "unit": "\u00b0C"
        },
        {
          "id": "6107df25c4aab8001b94e049",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 76.9,
          "phenomenon": "rel. Luftfeuchte",
          "sensor_type": "HDC1080",
          "unit": "%"
        },
        {
          "id": "6107df25c4aab8001b94e048",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 1013.9,
          "phenomenon": "Luftdruck",
          "sensor_type": "BMP280",
          "unit": "hPa"
        }
      ]
    }
  ],
  "total": 14
}
```

### Find stations in an area

Find the sensor stations inside a rectangle on the map, most recently reporting first, each with its newest readings.

**Inputs**

- West edge (longitude) (`west`, number, required): The longitude of the area's west edge, in decimal degrees, for example 7.55 for Münster. Keep each side under 5 degrees. From -180 to 180.
- South edge (latitude) (`south`, number, required): The latitude of the area's south edge, in decimal degrees, for example 51.9 for Münster. Keep each side under 5 degrees. From -90 to 90.
- East edge (longitude) (`east`, number, required): The longitude of the area's east edge, in decimal degrees, for example 7.7 for Münster. Keep each side under 5 degrees. From -180 to 180.
- North edge (latitude) (`north`, number, required): The latitude of the area's north edge, in decimal degrees, for example 52.0 for Münster. Keep each side under 5 degrees. From -90 to 90.
- Placement (`exposures`, list): Only stations placed like this. Choose Outdoors for weather and air quality. Leave empty for every station. One or more of: `outdoor` (Outdoors), `indoor` (Indoors), `mobile` (On the move (bike, car, bus)), `unknown` (Not stated).
- Measures (`phenomenon`, text): Only stations with a sensor for this. Leave empty for every station. Stations name their sensors themselves, mostly in German, so each choice shows the name it matches in brackets. One of: `Temperatur` (Temperature (Temperatur)), `rel. Luftfeuchte` (Relative humidity (rel. Luftfeuchte)), `Luftdruck` (Air pressure (Luftdruck)), `PM10` (Fine dust PM10), `PM2.5` (Fine dust PM2.5), `PM1` (Fine dust PM1), `PM4` (Fine dust PM4), `Beleuchtungsstärke` (Light level (Beleuchtungsstärke)), `UV-Intensität` (UV intensity (UV-Intensität)), `Lautstärke` (Noise level (Lautstärke)), and 4 more.
- Reported from (`reported_from`, date and time): Only stations that sent a reading at or after this moment. Use it to skip stations that have gone quiet. Leave empty for every station.
- Reported until (`reported_until`, date and time): With 'Reported from': the end of that period. Leave empty for up to now.
- How many stations (`limit`, number): How many stations to return (1-500). The total says how many matched. From 1 to 500. Default: `25`.

**Outputs**

- `has_more` (true/false): Whether more matched than were returned
- `stations` (list): The matching stations, most recently reporting first
- `total` (number): How many matched in total

**Example output**

```json
{
  "has_more": true,
  "stations": [
    {
      "created_at": "2021-08-02T12:03:49.808Z",
      "exposure": "outdoor",
      "group_tags": [],
      "height_m": null,
      "id": "6107df25c4aab8001b94e043",
      "last_reported_at": "2026-10-16T00:16:29.992Z",
      "latitude": 51.962788,
      "link": "https://opensensemap.org/explore/6107df25c4aab8001b94e043",
      "longitude": 7.631133,
      "model": "homeV2Lora",
      "name": "Stadtb\u00fccherei M\u00fcnster",
      "sensors": [
        {
          "id": "6107df25c4aab8001b94e04a",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 18.2,
          "phenomenon": "Temperatur",
          "sensor_type": "HDC1080",
          "unit": "\u00b0C"
        },
        {
          "id": "6107df25c4aab8001b94e049",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 76.9,
          "phenomenon": "rel. Luftfeuchte",
          "sensor_type": "HDC1080",
          "unit": "%"
        },
        {
          "id": "6107df25c4aab8001b94e048",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 1013.9,
          "phenomenon": "Luftdruck",
          "sensor_type": "BMP280",
          "unit": "hPa"
        }
      ]
    }
  ],
  "total": 830
}
```

### Find stations near a place

Find the sensor stations within a distance of a point, nearest first, each with what it measures and its newest readings.

**Inputs**

- Latitude (`latitude`, number, required): The point's latitude, for example 51.9607 for Münster. From -90 to 90.
- Longitude (`longitude`, number, required): The point's longitude, for example 7.6261 for Münster. From -180 to 180.
- Within (km) (`radius_km`, number): How far from the point to look, in kilometres (up to 50). From 0.1 to 50. Default: `2`.
- Placement (`exposures`, list): Only stations placed like this. Choose Outdoors for weather and air quality. Leave empty for every station. One or more of: `outdoor` (Outdoors), `indoor` (Indoors), `mobile` (On the move (bike, car, bus)), `unknown` (Not stated).
- Measures (`phenomenon`, text): Only stations with a sensor for this. Leave empty for every station. Stations name their sensors themselves, mostly in German, so each choice shows the name it matches in brackets. One of: `Temperatur` (Temperature (Temperatur)), `rel. Luftfeuchte` (Relative humidity (rel. Luftfeuchte)), `Luftdruck` (Air pressure (Luftdruck)), `PM10` (Fine dust PM10), `PM2.5` (Fine dust PM2.5), `PM1` (Fine dust PM1), `PM4` (Fine dust PM4), `Beleuchtungsstärke` (Light level (Beleuchtungsstärke)), `UV-Intensität` (UV intensity (UV-Intensität)), `Lautstärke` (Noise level (Lautstärke)), and 4 more.
- Reported from (`reported_from`, date and time): Only stations that sent a reading at or after this moment. Use it to skip stations that have gone quiet. Leave empty for every station.
- Reported until (`reported_until`, date and time): With 'Reported from': the end of that period. Leave empty for up to now.
- How many stations (`limit`, number): How many stations to return (1-500). The total says how many matched. From 1 to 500. Default: `25`.

**Outputs**

- `has_more` (true/false): Whether more matched than were returned
- `stations` (list): The matching stations, nearest first
- `total` (number): How many matched in total

**Example output**

```json
{
  "has_more": true,
  "stations": [
    {
      "created_at": "2021-08-02T12:03:49.808Z",
      "distance_km": 0.416,
      "exposure": "outdoor",
      "group_tags": [],
      "height_m": null,
      "id": "6107df25c4aab8001b94e043",
      "last_reported_at": "2026-10-16T00:16:29.992Z",
      "latitude": 51.962788,
      "link": "https://opensensemap.org/explore/6107df25c4aab8001b94e043",
      "longitude": 7.631133,
      "model": "homeV2Lora",
      "name": "Stadtb\u00fccherei M\u00fcnster",
      "sensors": [
        {
          "id": "6107df25c4aab8001b94e04a",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 18.2,
          "phenomenon": "Temperatur",
          "sensor_type": "HDC1080",
          "unit": "\u00b0C"
        },
        {
          "id": "6107df25c4aab8001b94e049",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 76.9,
          "phenomenon": "rel. Luftfeuchte",
          "sensor_type": "HDC1080",
          "unit": "%"
        },
        {
          "id": "6107df25c4aab8001b94e048",
          "latest_at": "2026-10-16T00:16:29.992Z",
          "latest_value": 1013.9,
          "phenomenon": "Luftdruck",
          "sensor_type": "BMP280",
          "unit": "hPa"
        }
      ]
    }
  ],
  "total": 7
}
```

### Get a sensor's latest reading

Read the newest value of one sensor, such as a station's temperature, as a number with its unit.

**Inputs**

- Station (`station_id`, text, required): The station's id or its link on opensensemap.org, for example https://opensensemap.org/explore/6107df25c4aab8001b94e043. The find and search actions return it as the station's id.
- Sensor (`sensor_id`, text, required): Which of the station's sensors to read. Choose a station first and this lists what it measures, with units.

**Outputs**

- `measured_at` (text): When it was taken, as an ISO 8601 timestamp in UTC
- `phenomenon` (text): What it measures, as the station names it (e.g. Temperatur)
- `sensor_id` (text): The sensor's id
- `sensor_type` (text): The sensor's hardware model
- `station_id` (text): The station's id
- `unit` (text): The unit its readings are in
- `value` (number): The newest reading, or empty if none

**Example output**

```json
{
  "measured_at": "2026-10-16T00:16:29.992Z",
  "phenomenon": "Temperatur",
  "sensor_id": "6107df25c4aab8001b94e04a",
  "sensor_type": "HDC1080",
  "station_id": "6107df25c4aab8001b94e043",
  "unit": "\u00b0C",
  "value": 18.2
}
```

### Get a sensor's readings over time

Read one sensor's readings over a period, newest first, with the lowest, highest and average value.

**Inputs**

- Station (`station_id`, text, required): The station's id or its link on opensensemap.org, for example https://opensensemap.org/explore/6107df25c4aab8001b94e043. The find and search actions return it as the station's id.
- Sensor (`sensor_id`, text, required): Which of the station's sensors to read. Choose a station first and this lists what it measures, with units.
- From (`from_time`, date and time): The start of the period to read. Leave empty for the last 24 hours.
- To (`to_time`, date and time): The end of the period to read. Leave empty for now.
- How many readings (`limit`, number): The most readings to return (1-10,000). From 1 to 10000. Default: `100`.

**Outputs**

- `average` (number): The average of the values returned
- `count` (number): How many readings were returned
- `from` (text): Start of the period read, as an ISO 8601 timestamp in UTC
- `has_more` (true/false): Whether the period held more readings than returned
- `highest` (number): The highest value returned
- `lowest` (number): The lowest value returned
- `phenomenon` (text): What it measures, as the station names it (e.g. Temperatur)
- `readings` (list): The readings, newest first
- `sensor_id` (text): The sensor's id
- `station_id` (text): The station's id
- `to` (text): End of the period read, as an ISO 8601 timestamp in UTC
- `unit` (text): The unit its readings are in

**Example output**

```json
{
  "average": 18.25,
  "count": 2,
  "from": "2026-10-15T00:17:38Z",
  "has_more": true,
  "highest": 18.3,
  "lowest": 18.2,
  "phenomenon": "Temperatur",
  "readings": [
    {
      "latitude": 51.962788,
      "longitude": 7.631133,
      "measured_at": "2026-10-16T00:16:29.992Z",
      "value": 18.2
    },
    {
      "latitude": 51.962788,
      "longitude": 7.631133,
      "measured_at": "2026-10-16T00:12:42.116Z",
      "value": 18.3
    }
  ],
  "sensor_id": "6107df25c4aab8001b94e04a",
  "station_id": "6107df25c4aab8001b94e043",
  "to": "2026-10-16T00:17:38Z",
  "unit": "\u00b0C"
}
```

### Get a station

Read one station in full: where it is, how it is placed, its owner's description and every sensor with its newest reading.

**Inputs**

- Station (`station_id`, text, required): The station's id or its link on opensensemap.org, for example https://opensensemap.org/explore/6107df25c4aab8001b94e043. The find and search actions return it as the station's id.

**Outputs**

- `created_at` (text): When it was registered, as an ISO 8601 timestamp in UTC
- `description` (text): The owner's description of the station
- `exposure` (text): Where it is placed: outdoor, indoor, mobile or unknown
- `group_tags` (list): The groups its owner tagged it with
- `height_m` (number): Its height above ground in metres, when the owner gave one
- `id` (text): The station's id
- `image_url` (text): Link to the owner's photo of it, if any
- `last_reported_at` (text): When it last sent a reading, as an ISO 8601 timestamp in UTC; empty if never
- `latitude` (number): Its latitude
- `link` (text): The station's page on opensensemap.org
- `location_set_at` (text): When it was put where it is now, as an ISO 8601 timestamp in UTC
- `longitude` (number): Its longitude
- `model` (text): The station's hardware kit
- `name` (text): The station's name
- `sensors` (list): What it measures, each with its newest reading
- `updated_at` (text): When its record last changed, as an ISO 8601 timestamp in UTC
- `website` (text): A website the owner linked, if any

**Example output**

```json
{
  "created_at": "2021-08-02T12:03:49.808Z",
  "description": "",
  "exposure": "outdoor",
  "group_tags": [],
  "height_m": null,
  "id": "6107df25c4aab8001b94e043",
  "image_url": "",
  "last_reported_at": "2026-10-16T00:16:29.992Z",
  "latitude": 51.962788,
  "link": "https://opensensemap.org/explore/6107df25c4aab8001b94e043",
  "location_set_at": "2021-08-02T12:03:49.802Z",
  "longitude": 7.631133,
  "model": "homeV2Lora",
  "name": "Stadtb\u00fccherei M\u00fcnster",
  "sensors": [
    {
      "id": "6107df25c4aab8001b94e04a",
      "latest_at": "2026-10-16T00:16:29.992Z",
      "latest_value": 18.2,
      "phenomenon": "Temperatur",
      "sensor_type": "HDC1080",
      "unit": "\u00b0C"
    },
    {
      "id": "6107df25c4aab8001b94e049",
      "latest_at": "2026-10-16T00:16:29.992Z",
      "latest_value": 76.9,
      "phenomenon": "rel. Luftfeuchte",
      "sensor_type": "HDC1080",
      "unit": "%"
    },
    {
      "id": "6107df25c4aab8001b94e048",
      "latest_at": "2026-10-16T00:16:29.992Z",
      "latest_value": 1013.9,
      "phenomenon": "Luftdruck",
      "sensor_type": "BMP280",
      "unit": "hPa"
    }
  ],
  "updated_at": "2026-10-16T00:16:30.012Z",
  "website": ""
}
```

### Get a station's latest readings

Read the newest value of everything a station measures, each with its unit and when it was taken.

**Inputs**

- Station (`station_id`, text, required): The station's id or its link on opensensemap.org, for example https://opensensemap.org/explore/6107df25c4aab8001b94e043. The find and search actions return it as the station's id.

**Outputs**

- `last_reported_at` (text): When its newest reading was taken, as an ISO 8601 timestamp in UTC
- `link` (text): The station's page on opensensemap.org
- `readings` (list): One reading per sensor
- `station_id` (text): The station's id
- `station_name` (text): The station's name

**Example output**

```json
{
  "last_reported_at": "2026-10-16T00:16:29.992Z",
  "link": "https://opensensemap.org/explore/6107df25c4aab8001b94e043",
  "readings": [
    {
      "measured_at": "2026-10-16T00:16:29.992Z",
      "phenomenon": "Temperatur",
      "sensor_id": "6107df25c4aab8001b94e04a",
      "sensor_type": "HDC1080",
      "unit": "\u00b0C",
      "value": 18.2
    },
    {
      "measured_at": "2026-10-16T00:16:29.992Z",
      "phenomenon": "rel. Luftfeuchte",
      "sensor_id": "6107df25c4aab8001b94e049",
      "sensor_type": "HDC1080",
      "unit": "%",
      "value": 76.9
    },
    {
      "measured_at": "2026-10-16T00:16:29.992Z",
      "phenomenon": "Luftdruck",
      "sensor_id": "6107df25c4aab8001b94e048",
      "sensor_type": "BMP280",
      "unit": "hPa",
      "value": 1013.9
    }
  ],
  "station_id": "6107df25c4aab8001b94e043",
  "station_name": "Stadtb\u00fccherei M\u00fcnster"
}
```

### Get a station's location history

List where a station has reported from, oldest first. A fixed station has one place; one on a bike or bus has many.

**Inputs**

- Station (`station_id`, text, required): The station's id or its link on opensensemap.org, for example https://opensensemap.org/explore/6107df25c4aab8001b94e043. The find and search actions return it as the station's id.
- From (`from_time`, date and time): The start of the period to read. Leave empty for the station's whole history.
- To (`to_time`, date and time): The end of the period to read. Leave empty for now.
- How many locations (`limit`, number): The most locations to return (1-10,000). From 1 to 10000. Default: `100`.

**Outputs**

- `has_more` (true/false): Whether more matched than were returned
- `locations` (list): The places it reported from, oldest first; the most recent ones when there are more than asked for
- `station_id` (text): The station's id
- `total` (number): How many matched in total

**Example output**

```json
{
  "has_more": false,
  "locations": [
    {
      "height_m": null,
      "latitude": 51.962788,
      "longitude": 7.631133,
      "recorded_at": "2021-08-02T12:03:49.802Z"
    }
  ],
  "station_id": "6107df25c4aab8001b94e043",
  "total": 1
}
```

### Get openSenseMap totals

Read how many stations openSenseMap has, how many readings it holds and how many arrived in the last minute.

**Inputs**: None.

**Outputs**

- `readings_last_minute` (number): How many readings arrived in the last minute
- `readings_total` (number): How many readings openSenseMap holds
- `stations` (number): How many stations are registered

**Example output**

```json
{
  "readings_last_minute": 7157,
  "readings_total": 10323420404,
  "stations": 17139
}
```

### Get readings across stations

Read one measurement, such as temperature or fine dust, from every station in an area or from stations you list: each station's latest value, or every reading in the period.

**Inputs**

- Measurement (`phenomenon`, text, required): What to read, such as temperature or fine dust. Stations name their sensors themselves, mostly in German, so each choice shows the name it matches in brackets. One of: `Temperatur` (Temperature (Temperatur)), `rel. Luftfeuchte` (Relative humidity (rel. Luftfeuchte)), `Luftdruck` (Air pressure (Luftdruck)), `PM10` (Fine dust PM10), `PM2.5` (Fine dust PM2.5), `PM1` (Fine dust PM1), `PM4` (Fine dust PM4), `Beleuchtungsstärke` (Light level (Beleuchtungsstärke)), `UV-Intensität` (UV intensity (UV-Intensität)), `Lautstärke` (Noise level (Lautstärke)), and 4 more. Default: `Temperatur`.
- Read from (`where`, text): Every station in an area on the map, or the stations you list. One of: `area` (Every station in an area), `stations` (Stations I choose). Default: `area`.
- West edge (longitude) (`west`, number): The longitude of the area's west edge, in decimal degrees, for example 7.55 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -180 to 180.
- South edge (latitude) (`south`, number): The latitude of the area's south edge, in decimal degrees, for example 51.9 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -90 to 90.
- East edge (longitude) (`east`, number): The longitude of the area's east edge, in decimal degrees, for example 7.7 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -180 to 180.
- North edge (latitude) (`north`, number): The latitude of the area's north edge, in decimal degrees, for example 52.0 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -90 to 90.
- Stations (`station_ids`, list): The stations to read, one per row: each station's id or its opensensemap.org link. Up to 50. Only when Read from is Stations I choose.
- Placement (`exposures`, list): Only stations placed like this. Choose Outdoors for weather and air quality. Leave empty for every station. One or more of: `outdoor` (Outdoors), `indoor` (Indoors), `mobile` (On the move (bike, car, bus)), `unknown` (Not stated).
- From (`from_time`, date and time): The start of the period to read. Leave empty for the last hour.
- To (`to_time`, date and time): The end of the period to read. Leave empty for now.
- Readings to return (`which`, text): Each station's newest reading, or all of them. One of: `latest` (Each sensor's latest reading), `all` (Every reading). Default: `latest`.
- How many readings (`limit`, number): The most readings to return (1-10,000). From 1 to 10000. Default: `100`.

**Outputs**

- `average` (number): The average of the values returned
- `from` (text): Start of the period read, as an ISO 8601 timestamp in UTC
- `has_more` (true/false): Whether more matched than were returned
- `highest` (number): The highest value returned
- `lowest` (number): The lowest value returned
- `phenomenon` (text): What was read, as stations name it
- `readings` (list): The readings, newest first
- `to` (text): End of the period read, as an ISO 8601 timestamp in UTC
- `total` (number): How many matched in total

**Example output**

```json
{
  "average": 16.76,
  "from": "2026-10-15T23:17:38Z",
  "has_more": false,
  "highest": 16.76,
  "lowest": 16.76,
  "phenomenon": "Temperatur",
  "readings": [
    {
      "exposure": "outdoor",
      "latitude": 51.961882,
      "longitude": 7.645843,
      "measured_at": "2026-10-16T00:17:36.259Z",
      "sensor_id": "682b3a8f7f7c2000081caa67",
      "station_id": "682b3a8f7f7c2000081caa66",
      "station_name": "Rudolf Carree",
      "unit": "\u00b0C",
      "value": 16.76
    }
  ],
  "to": "2026-10-16T00:17:38Z",
  "total": 31
}
```

### Search stations by name

Find stations whose name contains some text. Returns each station's id, name and position; use Get a station for the rest.

**Inputs**

- Name contains (`name`, text, required): Part of the station's name, for example 'Stadtbücherei'. Capital letters don't matter.
- How many stations (`limit`, number): The most stations to return (1-20). From 1 to 20. Default: `10`.

**Outputs**

- `stations` (list): The stations whose name matches
- `total` (number): How many stations were returned

**Example output**

```json
{
  "stations": [
    {
      "id": "6107df25c4aab8001b94e043",
      "latitude": 51.962788,
      "link": "https://opensensemap.org/explore/6107df25c4aab8001b94e043",
      "longitude": 7.631133,
      "name": "Stadtb\u00fccherei M\u00fcnster"
    }
  ],
  "total": 1
}
```

### Summarise readings over time

Work out a statistic, such as the average or the highest value, of each station's readings for every hour, day or other period, across an area or the stations you list.

**Inputs**

- Measurement (`phenomenon`, text, required): What to read, such as temperature or fine dust. Stations name their sensors themselves, mostly in German, so each choice shows the name it matches in brackets. One of: `Temperatur` (Temperature (Temperatur)), `rel. Luftfeuchte` (Relative humidity (rel. Luftfeuchte)), `Luftdruck` (Air pressure (Luftdruck)), `PM10` (Fine dust PM10), `PM2.5` (Fine dust PM2.5), `PM1` (Fine dust PM1), `PM4` (Fine dust PM4), `Beleuchtungsstärke` (Light level (Beleuchtungsstärke)), `UV-Intensität` (UV intensity (UV-Intensität)), `Lautstärke` (Noise level (Lautstärke)), and 4 more. Default: `Temperatur`.
- Statistic (`operation`, text): What to work out from each period's readings. One of: `arithmeticMean` (Average), `median`, `min` (Lowest), `max` (Highest), `sum` (Total), `standardDeviation` (Standard deviation), `variance`, `mode` (Most common value), `geometricMean` (Geometric mean), `harmonicMean` (Harmonic mean), `rootMeanSquare` (Root mean square). Default: `arithmeticMean`.
- Group readings (`window`, text): How long each period the statistic covers is. One of: `10m` (Every 10 minutes), `30m` (Every 30 minutes), `1h` (Every hour), `6h` (Every 6 hours), `1d` (Every day), `7d` (Every week). Default: `1h`.
- Read from (`where`, text): Every station in an area on the map, or the stations you list. One of: `area` (Every station in an area), `stations` (Stations I choose). Default: `area`.
- West edge (longitude) (`west`, number): The longitude of the area's west edge, in decimal degrees, for example 7.55 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -180 to 180.
- South edge (latitude) (`south`, number): The latitude of the area's south edge, in decimal degrees, for example 51.9 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -90 to 90.
- East edge (longitude) (`east`, number): The longitude of the area's east edge, in decimal degrees, for example 7.7 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -180 to 180.
- North edge (latitude) (`north`, number): The latitude of the area's north edge, in decimal degrees, for example 52.0 for Münster. Keep each side under 5 degrees. Only when Read from is Every station in an area. From -90 to 90.
- Stations (`station_ids`, list): The stations to read, one per row: each station's id or its opensensemap.org link. Up to 50. Only when Read from is Stations I choose.
- Placement (`exposures`, list): Only stations placed like this. Choose Outdoors for weather and air quality. Leave empty for every station. One or more of: `outdoor` (Outdoors), `indoor` (Indoors), `mobile` (On the move (bike, car, bus)), `unknown` (Not stated).
- From (`from_time`, date and time): The start of the period to read. Leave empty for the last 24 hours.
- To (`to_time`, date and time): The end of the period to read. Leave empty for now.

**Outputs**

- `from` (text): Start of the period read, as an ISO 8601 timestamp in UTC
- `phenomenon` (text): What was summarised, as stations name it
- `stations` (list): One entry per station sensor
- `statistic` (text): The statistic worked out, such as Average
- `to` (text): End of the period read, as an ISO 8601 timestamp in UTC
- `total` (number): How many station sensors were summarised
- `window` (text): How the readings were grouped, such as Every hour

**Example output**

```json
{
  "from": "2026-10-15T00:17:41Z",
  "phenomenon": "Temperatur",
  "stations": [
    {
      "exposure": "outdoor",
      "latest_value": 15.36,
      "latitude": 51.96422,
      "longitude": 7.645218,
      "sensor_id": "591f578c51d34600116a8ea6",
      "station_id": "591f578c51d34600116a8ea5",
      "station_name": "Wetterstation Erpho",
      "unit": "\u00b0C",
      "windows": [
        {
          "start": "2026-10-15T12:00:00.000Z",
          "value": 20.39
        },
        {
          "start": "2026-10-15T18:00:00.000Z",
          "value": 17.67
        },
        {
          "start": "2026-10-16T00:00:00.000Z",
          "value": 15.36
        }
      ]
    }
  ],
  "statistic": "Highest",
  "to": "2026-10-16T00:17:41Z",
  "total": 16,
  "window": "Every 6 hours"
}
```
