Externe Sensor-API

Sende Wetter- und Umweltdaten von deiner eigenen Sensorstation direkt in das AllskyKamera Netzwerk.

Base URLhttps://allskykamera.space/api/v1/weather.php
AuthentifizierungX-API-Key
MethodenGET POST
FormatJSON
Versionv1

Kurzüberblick

Die External Sensor API speichert Wetter- und Umweltmesswerte für Kameras im AllSkyKamera Netzwerk. Sie ist für technische Nutzer:innen gedacht, die eine eigene Wetterstation, ein SQM-Messgerät oder kleine Sensor-Nodes mit ihrer Kameraseite verbinden möchten.

Typische Quellen sind Wetterstationen, SQM, BME280, DS18B20, TSL2591 und eigene Umweltmesswerte. Die API veröffentlicht Werte nicht automatisch: Messwerte werden zuerst gespeichert und können danach im Userbereich für die Anzeige konfiguriert werden.

Basisdaten

Base URLhttps://allskykamera.space/api/v1/weather.php
Versionv1
Formatapplication/json
TransportHTTPS only
Erlaubte MethodenPOST zum Schreiben, GET zum Lesen
AuthentifizierungX-API-Key Header

Authentifizierung

Jede Anfrage muss den Kamera-Secret-Key im Header X-API-Key mitsenden. Der Key ordnet die Anfrage intern der passenden Kamera-ID zu; GET-Abfragen werden automatisch per Influx-Tag kamera.

X-API-Key: DEIN_GEHEIMER_KAMERA_KEY

Diesen Key niemals in öffentlichen Webseiten, GitHub-Repositories oder clientseitigem JavaScript verwenden.

POST: Sensordaten schreiben

POST schreibt externe Sensordaten in die gemeinsame InfluxDB. Alle hochgeladenen Werte werden im Measurement ext_sensors gespeichert und mit deiner Kamera-ID als kamera getaggt. Falls angegeben, wird ext_sensor als zusätzlicher Tag gespeichert.

Endpoint

POST https://allskykamera.space/api/v1/weather.php

Header

X-API-Key: DEIN_GEHEIMER_KAMERA_KEYContent-Type: application/json

JSON-Struktur

{
  "timestamp": "2026-05-20T21:15:00Z",
  "ext_sensor": "Dachstation",
  "fields": {
    "BME280_temp_c": 22.9,
    "BME280_hum_pct": 48.5,
    "DS18B20_temp_c": 21.3
  }
}
FeldPflichtFormatBeschreibung
timestampjaISO8601, UTCIm aktuellen Code zwingend erforderlich. Wird mit strtotime geparst; ungültige Werte liefern 400.
ext_sensorneinstringOptionaler Sensor- oder Stationsname. Leere Werte werden nicht als Tag geschrieben.
fieldsjaObjekt mit numerischen WertenNur numerische Werte werden geschrieben. Nicht-numerische Einträge werden ignoriert; bleibt nichts übrig, liefert die API 400 No numeric fields.

Fieldnamen werden vor dem Schreiben bereinigt: Zeichen außerhalb von A-Z, a-z, 0-9 und Unterstrich werden zu Unterstrichen. Nutze klare Einheiten im Feldnamen, z. B. temp_c, hum_pct, pressure_hpa oder sky_brightness.

Erfolgreiche Antwort

{
  "status": "ok"
}

GET: Sensordaten lesen

GET liest Messwerte aus der InfluxDB. Der API-Key bestimmt deine Kamera, und die Query enthält immer r["kamera"] == "ASKxxx". Eine andere Kamera kann nicht per Parameter abgefragt werden.

Endpoint

GET https://allskykamera.space/api/v1/weather.php

Header

X-API-Key: DEIN_GEHEIMER_KAMERA_KEY

Mögliche Werte für measurement und fields können über mode=metadata abgefragt werden.

Query-Parameter

NameTypStandardwertBeispielBeschreibung
measurementstringext_sensorsraspistatusAbzufragendes Influx-Measurement. Wird auf Buchstaben, Ziffern und Unterstriche bereinigt. Im aktuellen Code gibt es keine feste Allow-List.
fieldsstringleertemp_c,hum_pctKommagetrennte Field-Liste. Jedes Field wird auf Buchstaben, Ziffern und Unterstriche bereinigt; maximal 20 eindeutige Fields werden genutzt.
hoursinteger246Fallback-Zeitraum in Stunden, wenn start nicht gesetzt ist. Werte kleiner als 1 werden zu 1.
startdurationleer-6h, -7dAlternativer Start des Zeitbereichs. Erlaubt sind negative Durations mit s, m, h, d oder w. Ungültige Werte fallen auf hours zurück.
limitinteger5001000Maximale Anzahl zurückgegebener Zeilen nach Sortierung neueste zuerst. Werte kleiner als 1 werden zu 1.
pivot0|1010 liefert Long-Format. 1 dreht Fields in Spalten und liefert Wide-Format.
aggregatenone|mean|last|min|maxnonemeanErlaubt sind nur none, mean, last, min und max; andere Werte werden still zu none.
everyduration05mAggregationsintervall. Der Code akzeptiert 0, Sekunden, Minuten und Stunden wie 30s, 5m oder 1h. Ungültige Werte werden zu 0.
ext_sensorstringleerDachstationOptionaler Filter auf den Tag ext_sensor. Wird auf Buchstaben, Ziffern und Unterstriche bereinigt.

Long-Format

Das Long-Format ist der Standard. Jede Zeile enthält genau einen Field-Wert.

[
  {
    "time": "2026-05-20T21:15:00Z",
    "value": 18.42,
    "field": "raspiDiskFree",
    "measurement": "raspistatus",
    "ext_sensor": null,
    "kamera": "ASK999"
  }
]

Pivot-/Wide-Format

pivot=1 liefert eine Zeile pro Zeitpunkt mit Fields als Spalten. Numerische Strings werden zu Zahlen gecastet; leere Werte werden null.

[
  {
    "time": "2026-05-20T21:15:00Z",
    "_measurement": "ext_sensors",
    "kamera": "ASK999",
    "ext_sensor": "Dachstation",
    "temp_c": 22.9,
    "hum_pct": 48.5
  }
]

Meta-Daten abrufen

Mit mode=metadata können Nutzer:innen herausfinden, welche Measurements und Fields für ihren eigenen API-Key verfügbar sind. Die Antwort ist automatisch auf die zum Key gehörende Kamera beschränkt, gefiltert über den Influx-Tag kamera.

1. Metadaten abrufenmode=metadata
2. Field auswählenmeasurement / fields
3. Messdaten abrufenGET mit gewählten Parametern

Endpoint

GET https://allskykamera.space/api/v1/weather.php?mode=metadata

Optionaler Filter

measurement=raspistatus

curl

curl "https://allskykamera.space/api/v1/weather.php?mode=metadata" \
  -H "X-API-Key: DEIN_GEHEIMER_KAMERA_KEY"

curl "https://allskykamera.space/api/v1/weather.php?mode=metadata&measurement=raspistatus" \
  -H "X-API-Key: DEIN_GEHEIMER_KAMERA_KEY"

Beispielantwort

{
  "status": "ok",
  "mode": "metadata",
  "kamera": "ASK001",
  "range": "-30d",
  "measurements": [
    {
      "name": "raspistatus",
      "fields": ["raspiDiskFree", "raspiTemp"],
      "last_seen": "2026-05-20T12:34:00Z"
    },
    {
      "name": "ext_sensors",
      "fields": ["temp_c", "hum_pct", "pressure_hpa"],
      "ext_sensors": ["bme280_aussen", "tsl2591"],
      "last_seen": "2026-05-20T12:40:00Z"
    }
  ]
}

Ungültige measurement-Filter liefern HTTP 400 mit {"status":"error","error":"invalid_measurement"}. Der Metadaten-Zeitraum sind aktuell die letzten 30 Tage.

Typische Measurements und Felder

Der aktuelle Endpoint erzwingt für GET keine feste Measurement-Liste. Diese Namen sind im Code oder in vorhandenen Beispielen erkennbar und als Beispiele zu verstehen, nicht als vollständiger Katalog.

MeasurementTypische FelderHinweis
ext_sensorstemp_c, hum_pct, pressure_hpa, sky_brightnessMeasurement, in das POST-Uploads geschrieben werden.
SQMsqm, sky_brightnessPlausibles Abruf-Beispiel; tatsächliche Feldnamen hängen von den gespeicherten Daten ab.
raspistatusraspiDiskFreeWird in vorhandenen GET-Beispielen genutzt.

Antwortformate

POST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "ok"
}

GET

GET liefert ein JSON-Array. Es kann leer sein, wenn keine passenden Werte existieren.

Fehlercodes

HTTPBedeutungTypischer GrundBeispielantwort
400Ungültige AnfrageUngültiges JSON, fehlende timestamp/fields, ungültiger Zeitstempel oder keine numerischen Field-Werte.{"error":"Invalid JSON"}
401Fehlender oder ungültiger API-KeyHeader X-API-Key fehlt oder Key ist nicht in der Keyliste vorhanden.{"error":"Missing API key"}
405Falsche HTTP-MethodeJede Methode außer GET und POST.{"error":"Method not allowed"}
429Zu viele AnfragenMindestabstand, Tageslimit oder Monatslimit überschritten.{"error":"Rate limit (interval) exceeded","retry_after_seconds":42}
500Interner ServerfehlerKeyliste kann nicht geladen werden oder Influx-Write/Query ist fehlgeschlagen.{"error":"Failed to query Influx"}

Limits

Die Limits gelten pro Kamera und werden getrennt für Schreiben und Lesen gezählt.

POST / Datenupload-Limits

  • Mindestabstand: 59 Sekunden zwischen Schreibvorgängen.
  • Tageslimit: 5.000 POST-Anfragen.
  • Monatslimit: 130.000 POST-Anfragen.

GET / Datenabruf-Limits

  • Mindestabstand: 119 Sekunden zwischen Abrufen.
  • Tageslimit: 600 GET-Anfragen.
  • Monatslimit: 6.000 GET-Anfragen.

Dauerhaft höhere Frequenzen bitte vorher mit der Administration abstimmen.

Beispiele

curl POST

curl -X POST "https://allskykamera.space/api/v1/weather.php" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: DEIN_GEHEIMER_KAMERA_KEY" \
  -d '{"timestamp":"2026-05-20T21:15:00Z","ext_sensor":"Dachstation","fields":{"temp_c":22.9,"hum_pct":48.5,"pressure_hpa":1002.8}}'

curl GET

curl "https://allskykamera.space/api/v1/weather.php?measurement=ext_sensors&fields=temp_c,hum_pct&start=-6h&aggregate=mean&every=5m&pivot=1&limit=100" \
  -H "X-API-Key: DEIN_GEHEIMER_KAMERA_KEY"

Python POST

#!/usr/bin/env python3
import requests
from datetime import datetime, timezone

API_URL = "https://allskykamera.space/api/v1/weather.php"
API_KEY = "DEIN_GEHEIMER_KAMERA_KEY"
payload = {"timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), "ext_sensor": "Dachstation", "fields": {"temp_c": 22.9, "hum_pct": 48.5, "pressure_hpa": 1002.8}}
response = requests.post(API_URL, headers={"X-API-Key": API_KEY, "Content-Type": "application/json"}, json=payload, timeout=10)
print(response.status_code, response.text)

Python GET

import requests

API_URL = "https://allskykamera.space/api/v1/weather.php"
API_KEY = "DEIN_GEHEIMER_KAMERA_KEY"
params = {"measurement": "ext_sensors", "fields": "temp_c,hum_pct", "start": "-6h", "aggregate": "mean", "every": "5m", "pivot": 1, "limit": 100}
response = requests.get(API_URL, params=params, headers={"X-API-Key": API_KEY}, timeout=10)
print(response.status_code)
print(response.json()[:3])

ESP32 / Arduino POST

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "DEIN_WLAN";
const char* password = "DEIN_PASSWORT";
const char* apiUrl = "https://allskykamera.space/api/v1/weather.php";
const char* apiKey = "DEIN_GEHEIMER_KAMERA_KEY";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void loop() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(apiUrl);
    http.addHeader("Content-Type", "application/json");
    http.addHeader("X-API-Key", apiKey);
    String payload = R"({"timestamp":"2026-05-20T21:15:00Z","ext_sensor":"ESP32_Weather","fields":{"temp_c":23.4,"hum_pct":51.2}})";
    int httpCode = http.POST(payload);
    Serial.printf("HTTP: %d\n", httpCode);
    Serial.println(http.getString());
    http.end();
  }
  delay(60000);
}

Raspberry Pi Minimalbeispiel

from datetime import datetime, timezone
import requests

requests.post("https://allskykamera.space/api/v1/weather.php", headers={"X-API-Key": "DEIN_GEHEIMER_KAMERA_KEY"}, json={"timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"), "ext_sensor": "RaspberryPi", "fields": {"cpu_temp_c": 48.2}}, timeout=10)

Sicherheit und Datenschutz

Anzeige auf der Kameraseite

Daten werden zunächst gespeichert. Im Userbereich können Felder benannt, gruppiert, mit Einheiten versehen und sichtbar oder unsichtbar geschaltet werden. Nur aktivierte Sensoren erscheinen auf der Kameraseite.

1. Externe Sensoren im User-Bereich

User-Bereich mit Kachel „Externe Sensoren“

Im User-Profil kannst du die Konfiguration für externe Sensoren öffnen.

2. Sensor-Konfiguration

Sensor-Konfiguration mit Tabelle der externen Sensorfelder

In der Sensor-Konfiguration vergibst du Anzeigenamen, Gruppen, Einheiten und Sichtbarkeit.

3. Anzeige auf der Kameraseite

Kameraseite mit Bereich „Eigene Sensoren“ und Diagrammen

Auf der Kameraseite werden die ausgewählten Sensoren gruppiert als Diagramme angezeigt.