API-Auth dazu
automatisch auf INFLUX schalten, wenn es Chi-ID gibt zuzsätzlich option db=m zum erzwingen von Moing Anzeige Mongo/Influx im Datenstrom
This commit is contained in:
629
API_DOCUMENTATION.md
Normal file
629
API_DOCUMENTATION.md
Normal file
@@ -0,0 +1,629 @@
|
||||
# SensorAPI - API Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Die SensorAPI ist eine REST-API zur Abfrage von Umweltsensordaten (Lärm, Feinstaub, Temperatur, Radioaktivität). Sie unterstützt sowohl InfluxDB 1.8 (InfluxQL) als auch InfluxDB 2.0 (Flux) sowie MongoDB für Metadaten.
|
||||
|
||||
**Version:** 1.4.1
|
||||
**Basis-URL:** `http://<host>:<port>/api/`
|
||||
|
||||
---
|
||||
|
||||
## Technologie-Stack
|
||||
|
||||
- **Backend:** Node.js mit Express.js
|
||||
- **Datenbanken:**
|
||||
- InfluxDB 1.8/2.0 (Zeitreihendaten)
|
||||
- MongoDB (Sensor-Metadaten und -Eigenschaften)
|
||||
- **Sprachen:** JavaScript (ES6 Module)
|
||||
- **Key Dependencies:** axios, luxon, i18next, dotenv
|
||||
|
||||
---
|
||||
|
||||
## Unterstützte Sensortypen
|
||||
|
||||
| Typ | Beschreibung | Messgrößen |
|
||||
|-----|--------------|------------|
|
||||
| `noise` | Lärmsensoren | LA_max, LA_min, LA_eq, E10tel_eq |
|
||||
| `pm` | Feinstaubsensoren | P1, P2, P0 |
|
||||
| `thp` | Temperatur/Luftfeuchte/Druck | temperature, humidity, pressure |
|
||||
| `radioactivity` | Radioaktivitätssensoren | counts_per_minute |
|
||||
|
||||
---
|
||||
|
||||
## API Endpunkte
|
||||
|
||||
Alle Endpunkte folgen dem Schema: `GET /api/<command>?<parameter>`
|
||||
|
||||
### 1. **getsensordata**
|
||||
|
||||
Hauptendpunkt zum Abrufen von Sensordaten. Leitet je nach Sensortyp an spezialisierte Handler weiter.
|
||||
|
||||
**Endpunkt:** `/api/getsensordata`
|
||||
|
||||
**Pflichtparameter:**
|
||||
- `sensorid` (int) - Eindeutige Sensor-ID
|
||||
|
||||
**Optionale Parameter (abhängig vom Sensortyp):**
|
||||
|
||||
#### Für Lärmsensoren (`noise`):
|
||||
- `data` (string, default: 'live') - Art der Daten
|
||||
- `span` (int, default: 1) - Zeitspanne in Tagen
|
||||
- `daystart` (bool, default: null) - Start um 00:00:00 Uhr
|
||||
- `peak` (int, default: 70) - Schwellenwert für Lärmspitzen in dB
|
||||
- `since` (date, default: '1900-01-01T00:00:00Z') - Startdatum
|
||||
- `datetime` (date, default: null) - Spezifisches Datum/Zeit
|
||||
- `long` (bool, default: false) - Erweiterte Ausgabe
|
||||
- `sort` (int, default: 1) - Sortierung (1=aufsteigend, -1=absteigend)
|
||||
- `csv` (bool, default: false) - CSV-Ausgabe
|
||||
- `out` (string, default: '') - Ausgabeformat
|
||||
|
||||
#### Für Radioaktivitätssensoren (`radioactivity`):
|
||||
- `what` (string, default: 'day') - Art der Aggregation
|
||||
- `span` (int, default: 1) - Zeitspanne in Tagen
|
||||
- `avg` (int, default: 1) - Mittelwert-Intervall
|
||||
- `moving` (bool, default: false) - Gleitender Mittelwert
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getsensordata?sensorid=12345&span=7&peak=75
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"err": null,
|
||||
"values": [
|
||||
{
|
||||
"_time": "2025-11-04T10:00:00.000Z",
|
||||
"DNMS_noise_LA_max": 78.5,
|
||||
"DNMS_noise_LA_min": 45.2,
|
||||
"DNMS_noise_LA_eq": 65.3,
|
||||
"E10tel_eq": 72777980.45
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **getactdata**
|
||||
|
||||
Abrufen aktueller/historischer Rohdaten eines Sensors.
|
||||
|
||||
**Endpunkt:** `/api/getactdata`
|
||||
|
||||
**Parameter:**
|
||||
- `sensorid` (int) - Sensor-ID
|
||||
- `span` (int, optional) - Zeitspanne in Tagen
|
||||
- `datetime` (date, optional) - Startdatum
|
||||
- `sort` (int, optional) - Sortierung
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getactdata?sensorid=12345&span=1
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"err": null,
|
||||
"values": [
|
||||
{
|
||||
"_time": "2025-11-04T10:00:00.000Z",
|
||||
"DNMS_noise_LA_max": 78.62,
|
||||
"DNMS_noise_LA_min": 47.36,
|
||||
"DNMS_noise_LA_eq": null,
|
||||
"E10tel_eq": 72777980.45
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. **getavgdata**
|
||||
|
||||
Abrufen von Durchschnittswerten mit konfigurierbarem Zeitfenster.
|
||||
|
||||
**Endpunkt:** `/api/getavgdata`
|
||||
|
||||
**Pflichtparameter:**
|
||||
- `sensorid` (int) - Sensor-ID
|
||||
|
||||
**Optionale Parameter:**
|
||||
- `span` (int, default: 1) - Zeitspanne in Tagen
|
||||
- `datetime` (date, default: null) - Startdatum
|
||||
- `avg` (int, default: 10) - Mittelwert-Intervall in Minuten
|
||||
- `moving` (bool, default: true) - Gleitender Mittelwert
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getavgdata?sensorid=12345&span=7&avg=60&moving=true
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"start": "2025-10-28T10:00:00Z",
|
||||
"span": 7,
|
||||
"avg": 60,
|
||||
"moving": true,
|
||||
"count": 168,
|
||||
"values": [...]
|
||||
},
|
||||
"err": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. **getlongavg**
|
||||
|
||||
Langzeit-Durchschnittswerte über einen längeren Zeitraum.
|
||||
|
||||
**Endpunkt:** `/api/getlongavg`
|
||||
|
||||
**Pflichtparameter:**
|
||||
- `sensorid` (int) - Sensor-ID
|
||||
|
||||
**Optionale Parameter:**
|
||||
- `span` (int, default: 2) - Zeitspanne in Tagen
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getlongavg?sensorid=12345&span=30
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"span": 30,
|
||||
"values": [
|
||||
{
|
||||
"_stop": "2025-11-04T00:00:00.000Z",
|
||||
"LA_max": 75.3,
|
||||
"LA_min": 42.1,
|
||||
"LA_eq": 63.8
|
||||
}
|
||||
]
|
||||
},
|
||||
"err": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **getoneproperty**
|
||||
|
||||
Abrufen der Eigenschaften eines Sensors (Metadaten, Standort, etc.).
|
||||
|
||||
**Endpunkt:** `/api/getoneproperty`
|
||||
|
||||
**Pflichtparameter:**
|
||||
- `sensorid` (int) - Sensor-ID
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getoneproperty?sensorid=12345
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"err": null,
|
||||
"props": {
|
||||
"_id": 12345,
|
||||
"name": [{"name": "Hauptstraße"}],
|
||||
"type": "noise",
|
||||
"location": [{
|
||||
"id": "loc_123",
|
||||
"loc": {
|
||||
"type": "Point",
|
||||
"coordinates": [9.123, 48.456]
|
||||
},
|
||||
"indoor": false
|
||||
}],
|
||||
"othersensors": [
|
||||
{"name": "PM Sensor", "sid": 12346}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. **getmapdata**
|
||||
|
||||
Abrufen von Sensordaten für Kartendarstellung mit geografischer Filterung.
|
||||
|
||||
**Endpunkt:** `/api/getmapdata`
|
||||
|
||||
**Pflichtparameter:**
|
||||
- `type` (string) - Sensortyp (noise, pm, thp, radioactivity)
|
||||
|
||||
**Optionale Parameter (einer muss angegeben werden):**
|
||||
- `box` (string) - Begrenzungsbox: "west,south,east,north"
|
||||
- `poly` (JSON-Array) - Polygon-Koordinaten
|
||||
- `center` (Array) - Mittelpunkt [lng, lat]
|
||||
- `distance` (int, default: 10) - Radius in km (nur mit `center`)
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getmapdata?type=noise&box=9.0,48.0,9.5,48.5
|
||||
```
|
||||
|
||||
**Antwort:**
|
||||
```json
|
||||
{
|
||||
"err": null,
|
||||
"options": {
|
||||
"lastdate": "2025-11-04T10:30:00.000Z",
|
||||
"count": 25,
|
||||
"data": "map"
|
||||
},
|
||||
"values": [
|
||||
{
|
||||
"location": [9.123, 48.456],
|
||||
"id": 12345,
|
||||
"name": "Hauptstraße",
|
||||
"indoor": false,
|
||||
"lastseen": "2025-11-04T10:25:00.000Z",
|
||||
"value": 75.3,
|
||||
"weeks": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Wert-Kodierung:**
|
||||
- `value >= 0`: Aktueller Messwert
|
||||
- `value = -1`: Daten älter als 2 Stunden
|
||||
- `value = -2`: Daten älter als 7 Tage
|
||||
- `value = -3`: Daten älter als 30 Tage
|
||||
- `value = -4`: Daten älter als 365 Tage
|
||||
- `value = -5`: Keine Daten vorhanden
|
||||
|
||||
---
|
||||
|
||||
### 7. **getaddress**
|
||||
|
||||
Geocoding: Koordinaten aus Adresse ermitteln.
|
||||
|
||||
**Endpunkt:** `/api/getaddress`
|
||||
|
||||
**Parameter:**
|
||||
- `address` (string) - Adresse
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getaddress?address=Hauptstraße+10,+Stuttgart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. **getcitycoords**
|
||||
|
||||
Koordinaten einer Stadt abrufen.
|
||||
|
||||
**Endpunkt:** `/api/getcitycoords`
|
||||
|
||||
**Parameter:**
|
||||
- `city` (string) - Stadtname
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
GET /api/getcitycoords?city=Stuttgart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. **getakwdata**
|
||||
|
||||
Abrufen von Atomkraftwerks-Daten (spezialisiert).
|
||||
|
||||
**Endpunkt:** `/api/getakwdata`
|
||||
|
||||
---
|
||||
|
||||
## Zeitformat-Konvertierung
|
||||
|
||||
Die API akzeptiert verschiedene Zeitformate:
|
||||
|
||||
### InfluxDB 2.0 (Flux) Format:
|
||||
```
|
||||
start: -7d
|
||||
stop: now()
|
||||
```
|
||||
|
||||
### InfluxDB 1.8 (InfluxQL) Format:
|
||||
```
|
||||
now() - 7d
|
||||
now()
|
||||
```
|
||||
|
||||
### Absolute Zeitangaben (ISO 8601):
|
||||
```
|
||||
2025-11-04T10:00:00.000Z
|
||||
```
|
||||
|
||||
**Wichtig:** Bei der Verwendung von ISO-Zeitstempeln mit InfluxDB 1.8 werden diese automatisch in Anführungszeichen gesetzt.
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
Alle Endpunkte geben Fehler im folgenden Format zurück:
|
||||
|
||||
```json
|
||||
{
|
||||
"err": "ERROR_CODE",
|
||||
"values": []
|
||||
}
|
||||
```
|
||||
|
||||
**Häufige Fehlercodes:**
|
||||
- `NODATA` - Keine Daten gefunden
|
||||
- `SYNTAXURL` - Ungültige Query-Syntax
|
||||
- `NOPROPSREAD` - Eigenschaften konnten nicht gelesen werden
|
||||
- `NOPROPSFOUND` - Keine Eigenschaften gefunden
|
||||
- `CMNDUNKNOWN` - Unbekannter Befehl
|
||||
|
||||
---
|
||||
|
||||
## Spezielle Berechnungen für Lärmdaten
|
||||
|
||||
### Logarithmische Mittelwertbildung
|
||||
|
||||
Für Dezibel-Werte (LA_max) wird eine korrekte logarithmische Mittelwertbildung durchgeführt:
|
||||
|
||||
1. **Konvertierung zu linear:** `E10tel = 10^(LA_max/10)`
|
||||
2. **Arithmetischer Mittelwert:** `mean_E10tel = sum(E10tel) / count`
|
||||
3. **Rückkonvertierung zu dB:** `n_AVG = 10 * log10(mean_E10tel)`
|
||||
|
||||
### Peak-Zählung
|
||||
|
||||
Bei `getlongavg` mit `long=true` werden Lärmspitzen über einem Schwellenwert gezählt:
|
||||
|
||||
```json
|
||||
{
|
||||
"_time": "2025-11-04T12:00:00.000Z",
|
||||
"peakcount": 13,
|
||||
"n_AVG": 78.51,
|
||||
"count": 18
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Datenbank-Konfiguration
|
||||
|
||||
### Umgebungsvariablen (.env)
|
||||
|
||||
```bash
|
||||
# InfluxDB 1.8
|
||||
INFLUXHOST=localhost
|
||||
INFLUXPORT=8086
|
||||
INFLUXUSER=username
|
||||
INFLUXPASS=password
|
||||
INFLUXDB=sensor_data
|
||||
|
||||
# InfluxDB 2.0
|
||||
INFLUXTOKEN=your_token_here
|
||||
INFLUXDATABUCKET=sensor_data
|
||||
INFLUXORG=citysensor
|
||||
|
||||
# MongoDB
|
||||
MONGOHOST=localhost
|
||||
MONGOPORT=27017
|
||||
MONGODB=sensordb
|
||||
|
||||
# Datenbank-Auswahl
|
||||
DBASE=mongo # oder 'influx'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ausgabeformate
|
||||
|
||||
### JSON (Standard)
|
||||
Alle Endpunkte geben standardmäßig JSON zurück.
|
||||
|
||||
### CSV (Optional)
|
||||
Bei einigen Endpunkten kann `csv=true` übergeben werden:
|
||||
|
||||
```
|
||||
GET /api/getsensordata?sensorid=12345&csv=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Paginierung
|
||||
|
||||
Die API verwendet keine explizite Paginierung. Große Datenmengen sollten über `span` und `datetime` Parameter zeitlich eingeschränkt werden.
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Aktuell ist kein Rate Limiting implementiert. Dies sollte auf Proxy/Load-Balancer-Ebene erfolgen.
|
||||
|
||||
---
|
||||
|
||||
## Beispiel-Workflows
|
||||
|
||||
### Workflow 1: Karte mit Lärmsensoren anzeigen
|
||||
|
||||
1. Sensoren in Gebiet abrufen:
|
||||
```
|
||||
GET /api/getmapdata?type=noise&box=9.0,48.0,9.5,48.5
|
||||
```
|
||||
|
||||
2. Details für einen Sensor abrufen:
|
||||
```
|
||||
GET /api/getoneproperty?sensorid=12345
|
||||
```
|
||||
|
||||
3. Historische Daten abrufen:
|
||||
```
|
||||
GET /api/getactdata?sensorid=12345&span=7
|
||||
```
|
||||
|
||||
### Workflow 2: Lärmstatistik über eine Woche
|
||||
|
||||
1. Durchschnittswerte mit Lärmspitzen:
|
||||
```
|
||||
GET /api/getsensordata?sensorid=12345&span=7&peak=70&long=true
|
||||
```
|
||||
|
||||
2. Ergebnis analysieren:
|
||||
```json
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"_time": "2025-11-04T00:00:00.000Z",
|
||||
"peakcount": 13,
|
||||
"n_AVG": 78.51,
|
||||
"count": 1440,
|
||||
"LA_max_log_avg": 78.51
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Internationalisierung
|
||||
|
||||
Die API unterstützt mehrere Sprachen über i18next:
|
||||
- Deutsch (de)
|
||||
- Englisch (en)
|
||||
|
||||
Fehlermeldungen werden automatisch in der gewünschten Sprache zurückgegeben.
|
||||
|
||||
---
|
||||
|
||||
## Sicherheit
|
||||
|
||||
### API-Key-Authentifizierung
|
||||
|
||||
Die API unterstützt API-Key-Authentifizierung für programmatischen Zugriff.
|
||||
|
||||
#### Aktivierung
|
||||
|
||||
1. **API-Keys generieren:**
|
||||
```bash
|
||||
node generate-apikey.js 3
|
||||
```
|
||||
|
||||
2. **In .env konfigurieren:**
|
||||
```bash
|
||||
API_AUTH_REQUIRED=true
|
||||
API_KEYS=key1,key2,key3
|
||||
```
|
||||
|
||||
3. **Server neu starten**
|
||||
|
||||
#### Verwendung
|
||||
|
||||
API-Keys können auf zwei Arten übergeben werden:
|
||||
|
||||
**Option 1: HTTP-Header (empfohlen)**
|
||||
```bash
|
||||
curl -H "X-API-Key: your-api-key-here" \
|
||||
"http://localhost:3000/api/getactdata?sensorid=12345"
|
||||
```
|
||||
|
||||
**Option 2: Query-Parameter**
|
||||
```bash
|
||||
curl "http://localhost:3000/api/getactdata?sensorid=12345&apikey=your-api-key-here"
|
||||
```
|
||||
|
||||
#### Beispiel mit JavaScript/Node.js
|
||||
|
||||
```javascript
|
||||
import axios from 'axios'
|
||||
|
||||
const API_KEY = 'your-api-key-here'
|
||||
const BASE_URL = 'http://localhost:3000/api'
|
||||
|
||||
// Mit Header
|
||||
const response = await axios.get(`${BASE_URL}/getactdata`, {
|
||||
params: { sensorid: 12345 },
|
||||
headers: { 'X-API-Key': API_KEY }
|
||||
})
|
||||
|
||||
// Mit Query-Parameter
|
||||
const response2 = await axios.get(`${BASE_URL}/getactdata`, {
|
||||
params: {
|
||||
sensorid: 12345,
|
||||
apikey: API_KEY
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### Beispiel mit Python
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
API_KEY = 'your-api-key-here'
|
||||
BASE_URL = 'http://localhost:3000/api'
|
||||
|
||||
# Mit Header
|
||||
headers = {'X-API-Key': API_KEY}
|
||||
response = requests.get(f'{BASE_URL}/getactdata',
|
||||
params={'sensorid': 12345},
|
||||
headers=headers)
|
||||
|
||||
# Mit Query-Parameter
|
||||
response2 = requests.get(f'{BASE_URL}/getactdata',
|
||||
params={'sensorid': 12345, 'apikey': API_KEY})
|
||||
```
|
||||
|
||||
#### Fehlermeldungen
|
||||
|
||||
**401 Unauthorized - Kein API-Key angegeben:**
|
||||
```json
|
||||
{
|
||||
"err": "UNAUTHORIZED",
|
||||
"message": "API key required. Provide X-API-Key header or apikey query parameter."
|
||||
}
|
||||
```
|
||||
|
||||
**403 Forbidden - Ungültiger API-Key:**
|
||||
```json
|
||||
{
|
||||
"err": "FORBIDDEN",
|
||||
"message": "Invalid API key"
|
||||
}
|
||||
```
|
||||
|
||||
#### Best Practices
|
||||
|
||||
- **Niemals API-Keys im Code committen** - verwenden Sie Umgebungsvariablen
|
||||
- **Verschiedene Keys für verschiedene Clients** - ermöglicht granulare Kontrolle
|
||||
- **Keys regelmäßig rotieren** - besonders nach Mitarbeiterabgängen
|
||||
- **HTTPS verwenden** - schützt Keys bei Übertragung
|
||||
- **Keys sicher speichern** - z.B. in Secret Management Systemen
|
||||
- **Logging aktivieren** - überwachen Sie API-Zugriffe
|
||||
|
||||
### Weitere Sicherheitsmaßnahmen
|
||||
|
||||
Für Produktionsumgebungen sollten zusätzlich implementiert werden:
|
||||
- **HTTPS erzwungen** - verhindert Man-in-the-Middle-Angriffe
|
||||
- **CORS-Regeln konfiguriert** - beschränkt Browser-Zugriffe
|
||||
- **Rate Limiting aktiviert** - schützt vor Missbrauch
|
||||
- **IP-Whitelisting** - zusätzliche Zugriffskontrolle
|
||||
- **Request-Logging** - Audit-Trail für Compliance
|
||||
|
||||
---
|
||||
|
||||
## Support und Weiterentwicklung
|
||||
|
||||
Für Fragen, Bugs oder Feature-Requests siehe die Projekt-Repository-Dokumentation.
|
||||
|
||||
**Version History:**
|
||||
- 1.4.1: Unterstützung für InfluxDB 1.8 mit InfluxQL, logarithmische Mittelwertbildung für Lärmdaten
|
||||
Reference in New Issue
Block a user