Skip to main content
Version: 2.0.0

Use Case: Urban Air Quality Monitoring -> OGC SensorThings API

Status: fully modelled - all artifacts ship with the repository as reference artifacts under schemas/usecases/luftqualitaet-sta/. They can be imported through the ModelForge facade of a host application.

Scenario​

Urban air-quality monitoring stations continuously record:

  • Pollutant concentrations (NO2, PM2.5, CO)
  • Accompanying meteorological data (temperature, humidity)
  • GPS position

The raw data arrives via MQTT. In parallel, station master data (name, operator, calibration factors) resides in a PostgreSQL database.

The goal is to expose the measurement data as an OGC SensorThings APISensorThings APIA standardized API based on the OGC SensorThings API specification for accessing time series and IoT data. It enables structured retrieval and management of observations and related entities. (FROST), so that STA-compatible clients can retrieve the data.

TAF10 is intentionally not part of this use case. TAF10 is modelled separately as low-voltage grid telemetry in Use Case: TAF10 Low-Voltage Grid Protection.

Data flow​

Air-quality data flow

Readings where any pollutant's quality is "bad" (the filter checks no2.quality, pm25.quality and co.quality individually) are discarded; "suspect" readings are flagged and forwarded. The enrich step joins station master data from PostgreSQL by stationId and applies calibration factors. The fan-out runs one mapping per pollutant, each posting to the FROST /Observations endpoint.

In parallel (master-data sync, one-off / occasional): PostgreSQL master data is mapped to STAThing and STADatastream documents and posted to /FROST-Server/v1.1/Things and /Datastreams.

Data structures​

ElementURN
GeoPointurn:core:platform:civitas:element:common:GeoPoint:3ak90vqrog:1.0.0
Measurementurn:core:platform:civitas:element:luftqualitaet:Measurement:k9ta3hkxjf:1.0.0
AirQualityRawReadingurn:core:platform:civitas:element:luftqualitaet:AirQualityRawReading:42iv9tjv0c:1.0.0
StationCalibrationurn:core:platform:civitas:element:luftqualitaet:StationCalibration:aqokf4f3v2:1.0.0
StationMasterDataurn:core:platform:civitas:element:luftqualitaet:StationMasterData:ro0sfbbjfm:1.0.0
STALocationurn:core:platform:civitas:element:sta:STALocation:vktgfkub6y:1.0.0
STAThingurn:core:platform:civitas:element:sta:STAThing:1f0bfaterl:1.0.0
STAObservationurn:core:platform:civitas:element:sta:STAObservation:np3hnkoj04:1.0.0

Reference relationships (all via $ref, tracked in the dependency graph):

  • AirQualityRawReading -> Measurement -> GeoPoint
  • StationMasterData -> GeoPoint, StationCalibration
  • STAThing -> STALocation; STAObservation references its FROST Datastream by @iot.id

Mappings​

MappingURN
StationMasterData -> STAThingurn:core:platform:civitas:mapping:luftqualitaet:station-to-sta-thing:n34qmfpf7r:1.0.0
Air Quality NO2 -> STAObservationurn:core:platform:civitas:mapping:luftqualitaet:airquality-no2-to-observation:ca39n9nqqd:1.0.0
Air Quality PM2.5 -> STAObservationurn:core:platform:civitas:mapping:luftqualitaet:airquality-pm25-to-observation:wkk3xd31h0:1.0.0
Air Quality CO -> STAObservationurn:core:platform:civitas:mapping:luftqualitaet:airquality-co-to-observation:mgth0uv301:1.0.0

The station mapping copies stationName, stationType and metadata into the STAThing format. The per-pollutant mappings copy $.timestamp to phenomenonTime/resultTime, the pollutant value to result, and the quality flag to resultQuality.

Pipeline​

urn:core:platform:civitas:pipeline:luftqualitaet:Luftqualitaet-Import:v7v1oagoqd:1.0.0

NodeKindConfiguration
ConsumeMQTTsourceTopic luftqualitaet/readings/+, Element AirQualityRawReading
RouteOnContentfilterForward when no2.quality, pm25.quality and co.quality are all != "bad"
LookupRecordenrichKey $.stationId -> PostgreSQL station database
Transform NO2 / PM2.5 / COmappingOne mapping node per pollutant
InvokeHTTPsinkFROST POST /Observations

FROST server endpoints​

EndpointDescription
GET /FROST-Server/v1.1/ThingsAll stations
GET /FROST-Server/v1.1/DatastreamsAll data streams
GET /FROST-Server/v1.1/ObservationsAll measurements
GET /FROST-Server/v1.1/ObservedPropertiesNO2, PM2.5, CO
GET /FROST-Server/v1.1/Things(1)/DatastreamsDatastreams of one station
GET /FROST-Server/v1.1/Datastreams(1)/Observations?$top=10&$orderby=phenomenonTime descLatest 10 measurements

Analogous scenarios ship in schemas/usecases/taf10-grid-sta/ and schemas/usecases/smartmeter-sta/.