GBFS
Der Node liest Feeds nach der General Bikeshare Feed Specification (GBFS) von Sharing-Anbietern, wahlweise aus dem weltweiten Systemverzeichnis von MobilityData oder über manuell eingetragene URLs. Er wertet die Feeds free_bike_status, station_information und station_status aus, filtert die Ergebnisse auf Ihre Gebiete und gibt freie Fahrzeuge und Stationen über zwei Ausgänge aus.
- Node-Typ
- gbfs
- Paket
- @htag/node-red-contrib-hypertegrity-transportation
- Eingänge / Ausgänge
- 1 / 2
- Datenquelle
- Beliebiger GBFS-Feed (Version 1.x bis 2.x), Systemverzeichnis systems.csv von MobilityData
Wofür Sie den Node verwenden
GBFS ist der offene Standard, mit dem Anbieter von Leihfahrrädern, E-Scootern und ähnlichen Sharing-Fahrzeugen ihre Echtzeitdaten veröffentlichen. Ein GBFS-System besteht aus einer Discovery-Datei (gbfs.json), die auf einzelne Feeds verweist, zum Beispiel auf die Liste der frei stehenden Fahrzeuge oder auf Stationen mit Verfügbarkeiten. Der GBFS-Node übernimmt das Auffinden der Feeds, den Abruf und die räumliche Filterung, sodass Sie die Fahrzeuge und Stationen Ihrer Kommune ohne eigene Parser-Logik erhalten.
Typische Einsatzfälle sind:
- Mobilitätsdashboards, die verfügbare Leihräder und E-Scooter im Stadtgebiet in Echtzeit anzeigen.
- Auslastungsanalysen von Sharing-Stationen anhand von
num_bikes_availableundnum_docks_available. - Übernahme in einen Context Broker als Smart-Data-Model-Entitäten wie
BikeHireDockingStationoderVehicleüber den NGSI-LD Builder.
So funktioniert der Node
Auslösen
Eine eingehende Nachricht startet den Abruf. Optional nennt sie abweichende System-IDs oder URLs.
Systeme auflösen
Für gewählte System-IDs liest der Node die Discovery-URL aus dem Verzeichnis systems.csv von MobilityData (24 Stunden zwischengespeichert). Manuelle URLs werden direkt verwendet.
Feeds abrufen
Je System lädt der Node gbfs.json, danach free_bike_status sowie station_information und station_status. Alle Systeme werden parallel verarbeitet.
Filtern und ausgeben
Fahrzeuge und Stationen ohne gültige Koordinaten oder außerhalb der Lagefilter entfallen. Freie Fahrzeuge verlassen Ausgang 1, Stationen Ausgang 2, jeweils eine Nachricht je System.
Ergebnis: Je System ein Array freier Fahrzeuge und ein Array von Stationen mit Verfügbarkeiten, eingeschränkt auf Ihre Gebiete.
Der Node ist triggerbasiert. GBFS-Feeds ändern sich im Minutentakt; ein Inject-Node mit einem Intervall von ein bis fünf Minuten ist üblich. Das Systemverzeichnis systems.csv wird prozessweit im Speicher gehalten und nur alle 24 Stunden neu geladen.
Konfiguration
Der Bearbeitungsdialog hat zwei Registerkarten: Systeme und Lagefilter.
Registerkarte „Systeme“
| Feld | Typ | Standard | Bedeutung |
|---|---|---|---|
| Name | Text | leer | Anzeigename des Nodes im Flow. |
Systemliste (systemIds) | Liste mit Kontrollkästchen | leer | Alle Systeme aus systems.csv, filterbar nach Land, Ort und Freitext; „Nur ausgewählte“ blendet nicht gewählte Einträge aus. Die Statuszeile zeigt den Stand des Verzeichnis-Caches; der Button mit dem Aktualisierungssymbol lädt das Verzeichnis neu. Gespeichert werden die System-IDs, zum Beispiel dott-kaiserslautern. |
Manuelle GBFS URLs (manualUrls) | Liste mit Name, URL, Auth und Parameternamen | leer | Discovery-URLs (gbfs.json) von Systemen, die nicht im Verzeichnis stehen. Auth: None, Basic, Header oder Query; bei Header und Query nennen Sie die Parameternamen, mehrere durch einen senkrechten Strich getrennt. |
| Authentifizierung | Dynamische Eingabefelder | leer | Für Systeme und manuelle URLs mit Authentifizierung zeigt der Dialog Felder für Benutzername und Passwort (Basic) beziehungsweise für die genannten Parameter. |
apiKey | Passwort (Credential) | leer | Als Credential des Node-Typs hinterlegt. |
Registerkarte „Lagefilter“
| Feld | Typ | Standard | Bedeutung |
|---|---|---|---|
| Karten-Auswahl | Leaflet-Karte mit Zeichenwerkzeugen | Deutschland-Übersicht | Ein Klick auf die Karte ermittelt über Nominatim Stadtteil, Stadt und Landkreis an dieser Stelle und bietet sie als Gebiete an. Mit den Zeichenwerkzeugen legen Sie Rechtecke oder Kreise an. |
Aktive Filter (locations) | Sortierbare Liste | leer | Alle Gebiete mit Name (bearbeitbar) und Typ: Punkt mit Koordinaten (Kreis), Rechteck oder Verwaltungsgebiet (Polygon). Mehrere Filter werden mit ODER verknüpft. |
| Ort suchen | Suchfeld mit Vorschlägen | leer | Sucht über Nominatim nach Städten oder Bezirken und fügt deren Grenzpolygon hinzu (auf höchstens 50 Stützpunkte vereinfacht). |
| Manuelle Breiten- & Längengrade | Zwei Zahlenfelder mit Button „Punkt hinzufügen“ | leer | Legt einen Kreis mit 500 m Radius um die angegebenen Koordinaten an. |
Ohne Lagefilter gibt der Node alle Fahrzeuge und Stationen der gewählten Systeme aus.
Eingang
Jede Nachricht löst den Abruf aus. Zwei Eigenschaften können die konfigurierten Quellen für diese Nachricht ersetzen.
| Eigenschaft | Typ | Bedeutung |
|---|---|---|
msg.payload | beliebig | Löst den Abruf aus. Der Inhalt wird nicht ausgewertet. |
msg.systemIds | Array von Texten | Ersetzt die konfigurierten System-IDs, zum Beispiel ["dott-kaiserslautern"]. |
msg.manualUrls | Array von Texten oder Objekten | Ersetzt die konfigurierten manuellen URLs. Als Objekt mit url, optional name, authType und authParams. |
Die Lagefilter stammen immer aus der Konfiguration. Eigenschaften der eingehenden Nachricht werden in die Ausgangsnachrichten übernommen.
Ausgang
Der Node sendet je System und Feedtyp eine eigene Nachricht, aber nur, wenn nach der Filterung mindestens ein Eintrag übrig bleibt. Beide Ausgänge setzen msg.gbfs_system auf die System-ID (manual bei manuellen URLs) und msg.gbfs_type auf den Feedtyp. Fehlende oder leere Felder der unten genannten Pflichtfelder werden mit dem Text unknown belegt.
Ausgang 1: Free Bikes
msg.gbfs_type ist free_bikes. msg.payload ist ein Array frei stehender Fahrzeuge aus dem Feed free_bike_status.
[
{
"bike_id": "3f2a9c1e-5b7d-4e8a-9c2f-1d4b6e8a0c3f",
"lat": 49.4447,
"lon": 7.7689,
"is_reserved": false,
"is_disabled": false,
"vehicle_type_id": "escooter",
"last_reported": 1759305600,
"current_range_meters": 18500,
"rental_uris": {"android": "https://app.example.org/ride", "ios": "https://app.example.org/ride"},
"model": "unknown",
"type": "free_bike",
"system_id": "dott-kaiserslautern",
"system_name": "Dott Kaiserslautern"
}
]
| Feld | Bedeutung |
|---|---|
bike_id, lat, lon, is_reserved, is_disabled, vehicle_type_id, last_reported, current_range_meters, rental_uris, model | Felder aus dem GBFS-Feed; fehlende Werte werden zu unknown. current_range_meters ist die Restreichweite in Metern, last_reported ein Unix-Zeitstempel in Sekunden. |
type | Immer free_bike. |
system_id, system_name | System-ID und Name aus dem Verzeichnis beziehungsweise der manuellen URL. |
Ausgang 2: Stations
msg.gbfs_type ist stations. msg.payload ist ein Array von Stationen, bei dem station_information und station_status anhand der station_id zusammengeführt wurden. Es werden nur Stationen ausgegeben, an denen mindestens ein Fahrzeug verfügbar ist (num_bikes_available größer 0).
[
{
"station_id": "4711",
"name": "Hauptbahnhof Nord",
"short_name": "unknown",
"lat": 49.4360,
"lon": 7.7640,
"region_id": "unknown",
"rental_methods": ["KEY", "CREDITCARD"],
"capacity": 20,
"num_bikes_available": 7,
"num_bikes_disabled": 1,
"num_docks_available": 12,
"num_docks_disabled": 0,
"is_installed": true,
"is_renting": true,
"is_returning": true,
"last_reported": 1759305600,
"type": "station",
"system_id": "dott-kaiserslautern",
"system_name": "Dott Kaiserslautern"
}
]
| Feld | Bedeutung |
|---|---|
station_id, name, short_name, lat, lon, region_id, rental_methods, capacity | Stammdaten aus station_information. |
num_bikes_available, num_bikes_disabled, num_docks_available, num_docks_disabled, is_installed, is_renting, is_returning, last_reported | Verfügbarkeiten und Betriebsstatus aus station_status. |
type | Immer station. |
system_id, system_name | System-ID und Name. |
Weitere Felder der Feeds werden unverändert durchgereicht.
Beispiel-Flow
Das Paket bringt einen Beispiel-Flow mit. Sie importieren ihn in Node-RED über Menü → Importieren → Beispiele → @htag/node-red-contrib-hypertegrity-transportation → gbfs-data. Alternativ laden Sie die Datei gbfs-data.json herunter und importieren sie über Menü → Importieren.
Inject
Ein Inject-Node löst den Abruf manuell oder in einem festen Intervall aus.
GBFS
Der Node ruft das System dott-kaiserslautern ohne Lagefilter ab.
Zwei Debug-Nodes
Ausgang 1 zeigt freie Scooter, Ausgang 2 Stationen in der Seitenleiste an.
Beispiel-Flow als JSON anzeigen
[
{"id": "tab1", "type": "tab", "label": "Gbfs-data", "disabled": false, "info": ""},
{"id": "inject1", "type": "inject", "z": "tab1", "name": "", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 120, "y": 100, "wires": [["gbfs1"]]},
{"id": "gbfs1", "type": "gbfs", "z": "tab1", "name": "", "systemIds": ["dott-kaiserslautern"], "manualUrls": [], "locations": [], "x": 370, "y": 100, "wires": [["debug1"], ["debug2"]]},
{"id": "debug1", "type": "debug", "z": "tab1", "name": "Freie Scooter", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 600, "y": 100, "wires": []},
{"id": "debug2", "type": "debug", "z": "tab1", "name": "Stationen", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 580, "y": 160, "wires": []}
]
Status und Fehler
| Anzeige | Bedeutung |
|---|---|
| Grüner Punkt „Systeme bereit“ | Der Node ist bereit (Status nach dem Start). |
| Gelber Punkt „Lade systems.csv...“ | Das Systemverzeichnis wird gerade heruntergeladen (Status nach dem Start). |
| Roter Ring „Fehler: …“ | Der letzte Download des Systemverzeichnisses ist fehlgeschlagen (Status nach dem Start). |
| Blauer Punkt „Lade Daten...“ | Der Abruf läuft. |
| Grüner Punkt „Daten aktualisiert“ | Alle Quellen wurden verarbeitet. Einzelne fehlgeschlagene Feeds erzeugen nur Warnungen. |
| Roter Ring „Fehler beim Laden“ | Der Abruf konnte nicht gestartet werden. Fehlermeldung: „Keine Systeme oder manuelle URLs konfiguriert“. |
| Warnung „Fehler beim Laden der systems.csv: …“ | Das Verzeichnis ist nicht erreichbar (Timeout nach 10 Sekunden, Verbindungs- oder HTTP-Fehler, ungültige Datei). System-IDs können dann nicht aufgelöst werden; manuelle URLs funktionieren weiterhin. |
| Warnung „System-ID nicht gefunden oder fehlende URL: …“ | Die System-ID steht nicht im Verzeichnis oder hat dort keine Discovery-URL. |
| Warnung „Zeitüberschreitung beim Abrufen von … (Timeout nach 8s)“, „Verbindungsfehler beim Abrufen von …“, „HTTP-Fehler … bei …“ | Ein Feed des genannten Systems ist nicht erreichbar. |
| Warnung „Ungültige GBFS-Discovery-Datei für …“, „Leere Antwort vom Feed-Server für …“, „Ungültige JSON-Struktur im Feed …“ | Die Antwort entspricht nicht dem GBFS-Format. |
| Warnung „Fehler beim Abrufen der Free-Bike-Daten für …“, „Fehler beim Abrufen der Stationsdaten für …“, „Feed-Fehler (…)“ | Sonstige Fehler beim Verarbeiten eines Feeds. |
Fehler werden über node.error gemeldet und können mit einem Catch-Node abgefangen werden. Warnungen erscheinen in der Debug-Seitenleiste.
Hinweise
- GBFS-Versionen: Der Node findet Feeds in Discovery-Dateien der Versionen 1.x bis 2.x (mit und ohne Sprachebene) und liest die Feeds
free_bike_status,station_informationundstation_status. - Rate Limits: Viele Anbieter begrenzen die Abrufhäufigkeit. Die GBFS-Feeds enthalten ein Feld
ttl, das die empfohlene Gültigkeitsdauer in Sekunden nennt. Wählen Sie das Inject-Intervall nicht kürzer als diesen Wert. Jede Anfrage hat ein Timeout von 8 Sekunden. - Smart Data Models: Die Ausgabe enthält die Rohfelder der GBFS-Feeds. Die Abbildung auf Smart Data Models wie
BikeHireDockingStation(Stationen) oderVehicle(freie Fahrzeuge) erfolgt im nachgelagerten NGSI-LD Builder. - Metrische Einheiten: Radien im Lagefilter werden in Metern angegeben,
current_range_metersist die Restreichweite in Metern. - Editor-Dienste: Karte, Gebietssuche und Klick-Erkennung nutzen Leaflet, OSM-Kartenkacheln und Nominatim aus dem Internet. Das Verzeichnis
systems.csvwird von GitHub (MobilityData) geladen. - Personenbezogene Daten: Fahrzeug-IDs (
bike_id) und Standorte frei stehender Fahrzeuge können bei dauerhafter Speicherung Bewegungsprofile einzelner Fahrten erkennbar machen. Die GBFS-Spezifikation verlangt zwar rotierende IDs, dennoch sollten Sie Fahrzeugdaten nur aggregiert oder mit kurzer Aufbewahrung speichern und keine Fahrten einzelnen Personen zuordnen.rental_urisenthalten Links zu den Apps der Anbieter. - Lizenzen: Die Nutzungsbedingungen der Feeds legt der jeweilige Anbieter fest; das Verzeichnis
systems.csvverlinkt bei vielen Systemen auf Lizenzinformationen.