HTTP-Anfragen
Wie du deine Sensoren über HTTP mit Stadtpuls reden lässt.
Stadtpuls erlaubt dir, Sensor-Daten über HTTP hinzuzufügen. Dies eröffnet viele Möglickeiten, wie du mit der Plattform interagieren kannst. Zum Beispiel könnte ein Raspberry Pi, ein Arduino Board, dein Browser, ein Webserver oder dein Smartphone (um nur einige zu nennen) Daten sammeln und sie auf Stadtpuls veröffentlichen. Voraussetzung ist, dass dein Endgerät das "Hypertext Transfer Protocol" (HTTP) spricht.
Im erstes Beispiel erklären wir dir, wie du mit einem einfachen Python-Script Werte auf Stadtpuls hinzufügen kannst.
Daten senden mit Python
Voraussetzungen
Folgende Voraussetzungen sollten erfüllt sein:
✓ Du hast einen Stadtpuls Account
✓ Du hast einen Token erstellt und dir sicher gespeichert
✓ Du hast bereits einen Sensor vom Typ HTTP angelegt
✓ Du hast Python (3)* installiert
✓ Du hast einen Code Editor wie VSCode, Pycharm, Sublime Text, VIM, Nano oder ähnlich installiert
✓ Du hast ein Terminal Emulator installiert**
* Python 2 geht auch, das Script ist jedoch nur mit Python 3 getestet und möglicherwiese nicht kompatibel mit Python 2.
** Jede Plattform hat ihr eigenes Terminal. Wir gehen hier von Linux oder MacOS aus und verwenden die BASH Shell. Für Windows gibt es z.B. die Powershell oder WSL, um zu dem gleichen Ergebnis zu kommen.
Python Script Schritt für Schritt
Erstelle eine neue Datei mit dem Name stadtpuls.py
. Als erstes solltest du folgende Zeilen einfügen und speichern:
import requests
import json
Diese Zeilen sagen Python, welche Bibliotheken du benötigst. Führe die Datei aus, um zu sehen was passiert. Starte eine neue Shell Session in deinem Terminal und navigiere zu deinem Python Script. Dann führe folgenden Befehl aus:
python3 stadtpuls.py
Wenn du keinen Fehler bekommst, bist du bereit, weiter zu machen. Es könnte aber passieren, dass eine Fehlermeldung erscheint:
Traceback (most recent call last):
File "stadtpuls.py", line 2, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
Das bedeutet, dass die Bibliothek requests
nicht installiert ist. Diese kannst du mit dem Package Manager pip
und folgendem Befehl intallieren:
pip install requests
Die json
-Bibliothek ist eine System-Bibliothek und sollte standardmäßig vorhanden sein. Probier es noch einmal. Nun sollte dein Script keinen Fehler mehr melden.
Als nächstes erstellen wir einige Variablen, die wir im Laufe des Scripts benötigen. Unterhalb von den import
-Befehlen fügen wir die folgenden Zeilen ein:
sensor_url = "https://api.stadtpuls.com/api/v3/sensors/<DEINE SENSOR ID>/records"
token = "<DEINEN TOKEN HIER EINFÜGEN>"
headers = {"authorization": "Bearer {}".format(token)}
json = {"measurements": [42]}
Du solltest hier deine eigene Sensor-URL und deinen Token einfügen.
(Bonus. Gehe auf die Seite jwt.io und füge deinen Token in das Feld "Encoded" ein. Damit kannst du sehen, welche Informationen in dieser Zeichenkette gespeichert sind.)
Die Variable headers
ist für die HTTP POST Anfrage und transportiert deinen Token, damit dein Sensor die Daten erhält. Ohne diese würde die API deine Anfrage zurückweisen, weil du nicht authorisiert bist.
Die Variable json
beinhaltet deine Daten. Wir geben hier einen Wert von 42
in das Array measurements
ein. Die API erwartet diese Struktur und würde ein JSON, das anders benannt ist, zurückweisen.
Deine Sensor-URL kannst du in deinem Account auf der Seite deines Sensors finden. Du kannst die URL auch im Browser öffnen, um eine HTTP GET Anfrage zu stellen. Wenn dein Sensor noch keine Daten hat, solltest du so etwas sehen:
{"data":[]}
Damit sind die Vorbereitungen abgeschlossen. Nun folgt die eigentliche Anfrage mit der requests
-Bibliothek. Füge die folgenden Zeilen an dein Script an.
try:
response = requests.post(sensor_url, json=json, headers=headers)
if response.status_code != 201:
print("Fehler beim Senden der Daten: {}".format(response.status_code))
else:
print("Daten wurden erfolgreich gesendet")
except requests.exceptions.RequestException as error:
print(error)
Wir starten diesen Block mit einem try
und except
Block. Dadurch können wir etwaige Fehler, die der Code innnerhalb des try
Blocks werfen könnte, mit dem except
Block auffangen. In diesem Fall fangen wir mit requests.exceptions.RequestException
nur Fehler der requests
Bibliothek auf. Syntaxfehler würden ebenfalls einen Fehler erzeugen, werden aber nicht mit unserem print
Befehl gehandhabt.
Die Zeile
response = requests.post(sensor_url, json=json, headers=headers)
ist der Kern unseres Scriptes. Das object requests macht eine HTTP POST Anfrage (requests.post
) an die URL sensor_url
mit den Header-Informationen headers
und den Daten json
.
Das Ergebnis der Anfrage speichern wir in der Variable response
und führen mit der Zeile
if response.status_code != 201:
einen Test aus, ob die Antwort der API etwas anderes als den HTTP Statuscode 201
hat. Wenn dies der Fall ist, wird eine Fehlermeldung in der folgenden Zeile mit dem print
Befehl ausgegeben. Wenn der erwartetete Statuscode 201
von der API zurückgegeben wurde, geben wir eine Erfolgsmeldung aus.
Das Gesamte Python-Script
Hier siehst du nochmal das gesamte Python-Script.
import requests
import json
sensor_url = "https://api.stadtpuls.com/api/v3/sensors/<DEINE SENSOR ID>/records"
token = "<DEINEN TOKEN HIER EINFÜGEN>"
headers = {"authorization": "Bearer {}".format(token)}
json = {"measurements": [42]}
try:
response = requests.post(sensor_url, json=json, headers=headers)
if response.status_code != 201:
print("Fehler beim Senden der Daten: {}".format(response.status_code))
else:
print("Daten wurden erfolgreich gesendet")
except requests.exceptions.RequestException as error:
print(error)
Herzlichen Glückwunsch! Du hast dein erstes Stadtpuls Python-Script erstellt.
Daten senden mit Javascript
Javascript kann auf verschiedenste Weisen ausgeführt werden, mit Node.js, mit Replit.com, auf codesandbox.io, via GitHub Codespaces, auf JSBin und an vielen anderen Plätzen. Um die Einstiegshürde so gering wie möglich zu halten, empfehlen wir hier JSBin oder für Firefox-Nutzer:innen den Multi Line Editor der Web Console.
Voraussetzungen
Folgende Voraussetzungen sollten erfüllt sein:
✓ Du hast einen Stadtpuls Account
✓ Du hast einen Token erstellt und dir sicher gespeichert
✓ Du hast bereits einen Sensor vom Type HTTP angelegt
✓ Du hast entweder JSBin oder den FireFox Multi Line Editor *
* Brave, Safari, Chrome, Edge Benutzer:innen können mit SHIFT + ENTER direkt in der Console schreiben.
Javascript Schritt für Schritt
Um sicherzustellen, dass Firefox uns nicht mit Fehlern ärgert, die uns sagen, dass unsere const
Variablen bereits definiert sind, kapseln wir unser gesamtes Script in einem Closure. Alle weiteren Befehlszeilen werden in die geschwungenen Klammern geschrieben.
{
// Dein Code kommt hier rein
}
Als nächstes erstellen wir einige Variablen, die wir im Laufe unseres Scripts benötigen. Innerhalb unserer geschwungenen Klammern fügen wir folgende Zeilen ein:
const url = "https://api.stadtpuls.com/api/v3/sensors/<DEINE SENSOR ID>/records";
const token = "<DEIN TOKEN HIER EINFÜGEN>";
const headers = new Headers({
authorization: `Bearer ${token}`,
"content-type": "application/json",
});
const data = {
measurements: [42],
};
Du solltrst hier deine eigene Sensor-URL und deinen eigenen Token einfügen.
(Bonus. Gehe auf die Seite jwt.io und füge deinen Token in das Feld "Encoded" ein. Damit kannst du sehen, welche Informationen in dieser Zeichenkette gespeichert sind.)
Die Variable headers
ist für die HTTP POST Anfrage und transportiert deinen Token damit dein Sensor die Daten erhält und den content-type
der Anfrage, also was wir denn genau senden. In diesem Fall ist das application/json
also JSON. Ohne diese Einträge würde die API deine Anfrage zurückweisen, weil du nicht authorisiert bist oder den falschen Datentyp sendest.
Die Variable data
beinhaltet deine Daten. Wir geben hier einen Wert von 42
in das Array measurements
ein. Die API erwartet diese Struktur und würde ein JSON, das anders benannt ist, zurückweisen.
Deine Sensor-URL kannst du in deinem Account auf der Seite deines Sensors finden. Du kannst die URL auch im Browser öffnen, um eine HTTP GET Anfrage zu stellen. Wenn dein Sensor noch keine Daten hat, solltest du so etwas sehen:
{"data":[]}
Damit sind die Vorbereitungen abgeschlossen.
Nun folgt die eigentliche Anfrage mit der browsereigenen Methode fetch
. Füge die folgenden Zeilen an dein Script unterhalb deiner data
Variable an.
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(data),
})
Wir übergeben an die Methode fetch
die url
zu deinem Sensor und ein Objekt mit unserem headers
und data
. data
wird mit der Methode JSON.stringify
von einem Javascript Objekt in eine Zeichenkette umgewandelt und als body
an fetch
übergegeben.
fetch
gibt uns ein Promise zurück. Dieses Promise verarbeiten wir mit dem folgenden Befehl, den wir direkt an die schließenden Klammern von unserem fetch
anhängen.
.then((response) => {
if (!response.ok) {
throw new Error("response not ok");
}
if (response.status !== 201) {
throw new Error("status not 201");
}
return reponse.json();
})
Der Befehl .then
erwartet eine Funktion, welche das Ergebnis des erfolgreich aufgelösten Promise von fetch
übernimmt. Das Ergebnis wird als Argument an die Funktion gegeben. In unserem Fall nennen wir das Ergebnis response
. Wir führen mit den Abfragen if (!response.ok)
(if response not okay) und if (response.status !== 201)
(if status code is not 201) zwei Tests durch, um sicher zu stellen, dass unsere Anfrage erfolgreich war. Wenn eine der beiden Bedingungen nicht erfüllt ist, wird ein Fehler ausgelöst. Wir könnten hier schon mit unserem Script fertig sein. Der Vollständigkeit halber verarbeiten wir jedoch die Informationen aus der Antwort. Mit den Befehlen return reponse.json();
geben wir ein weiteres Promise von der Methode .json()
an die nächste .then
Methode.
Dafür fügen wir an unser erste .then
Methode ein weitere an.
.then((json) => {
console.info(json);
})
Das Ergebnis der Methode .json()
aus der vorherigen .then
Methode wird wiederum als Argument an die Funktion gegeben. In unserem Fall wird das Ergebnis nur in der Konsole ausgegeben.
Zu guter letzt fügen wir eine andere Methode, genannt .catch
, an.
.catch((error) => {
console.error(error);
});
Damit werden alle Error
, die wir innnerhalb unserer .then
Methoden werfen und auch Fehler, die die fetch
Methode werfen könnte, "gefangen" und verarbeitet.
Das gesamte Javascript
Das gesamte Javascript siehst du nochmal hier.
{
const url = "https://api.stadtpuls.com/api/v3/sensors/<DEINE SENSOR ID>/records";
const token = "<DEIN TOKEN HIER EINFÜGEN>";
const headers = new Headers({
authorization: `Bearer ${token}`,
"content-type": "application/json",
});
const data = {
measurements: [42],
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => {
if (!response.ok) {
throw new Error("response not ok");
}
if (response.status !== 201) {
throw new Error("status not 201");
}
return response.json();
})
.then((json) => {
console.info(json);
})
.catch((error) => {
console.error(error);
});
}
Herzlichen Glückwunsch! Du hast dein erstes Stadtpuls Javascript erstellt.