Redis-API-Referenz
Alle Librescoot-Services kommunizieren über Redis auf dem MDB. Hier findest du State-Hashes, Command-Queues und Pub/Sub-Channels.
Der Datenspeicher läuft auf dem MDB unter
192.168.7.1:6379. Das DBC verbindet sich per USB-Ethernet. Von einem verbundenen Rechner aus:
redis-cli -h 192.168.7.1 # Oder per SSH-Tunnel: ssh -L 6379:localhost:6379 root@<mdb-ip>
Seit 1.2 läuft statt Redis ein Valkey. Gleiches Protokoll, gleicher Port, und
redis-cli bleibt als Kompatibilitäts-Symlink erhalten. Alle Befehle auf dieser Seite funktionieren also unverändert, ebenso die --redis-*-Flags der Services.
Go-Services nutzen die redis-ipc-Bibliothek, die go-redis um Helfer für Hash-Publishing, Queue-Verarbeitung und Pub/Sub erweitert. Im README stehen die Patterns, die quer durch alle Services verwendet werden.
State-Hashes
Zustand wird in Redis-Hashes abgelegt. Services aktualisieren Felder per HSET und publizieren Änderungsbenachrichtigungen auf gleichnamigen Channels.
vehicle
redis-cli -h 192.168.7.1 HGETALL vehicle
| Feld | Werte | Beschreibung |
|---|---|---|
state | stand-by / parked / hop-on / hop-on-learning / ready-to-drive / waiting-seatbox / shutting-down / updating / waiting-hibernation / waiting-hibernation-advanced / waiting-hibernation-seatbox / waiting-hibernation-confirm | Betriebszustand des Fahrzeugs |
handlebar:position | on-place / off-place | Lenkerposition-Sensor |
handlebar:lock-sensor | locked / unlocked | Lenkschloss-Zustand |
seatbox:lock | open / closed | Helmfach-Verschluss |
seatbox:button | on / off | Helmfach-Öffner-Taste |
kickstand | up / down | Seitenständer |
brake:left / brake:right | on / off | Bremshebel-Zustand |
blinker:switch | left / right / both / off | Blinker-Schalterposition |
blinker:state | on / off | Blinker aktuell aktiv |
main-power | on / off | Hauptstrom-Zustand |
horn:button | on / off | Hupen-Taste |
battery:0 / battery:1
redis-cli -h 192.168.7.1 HGETALL battery:0
| Feld | Typ | Beschreibung |
|---|---|---|
present | true / false | Ist ein Akku eingelegt |
state | string | Akkuzustand |
charge | integer (%) | Ladestand |
voltage | integer (mV) | Akkuspannung |
current | integer (mA) | Akkustrom |
temperature:0–temperature:3 | integer (°C) | Temperatursensoren |
state-of-health | integer (%) | Akku-Gesundheit |
cycle-count | integer | Ladezyklen |
serial-number | string | Seriennummer des Akkus |
fw-version | string | BMS-Firmware-Version |
engine-ecu
redis-cli -h 192.168.7.1 HGETALL engine-ecu
| Feld | Typ | Beschreibung |
|---|---|---|
speed | integer (km/h) | Geschwindigkeit |
rpm | integer | Motor-Drehzahl |
odometer | integer (m) | Gesamtstrecke |
motor:voltage | integer (mV) | Motorspannung |
motor:current | integer (mA) | Motorstrom |
temperature | integer (°C) | ECU-Temperatur |
throttle | on / off | Gasgriff aktiv |
kers | on / off | Rekuperation aktiv |
kers-reason-off | string | Warum KERS aus ist (none / cold / hot) |
gear | integer | Gangstufe |
fw-version | hex string | ECU-Firmware-Version |
internet
| Feld | Beschreibung |
|---|---|
status | Verbindungsstatus (connected / disconnected) |
access-tech | Access-Technologie (z.B. LTE) |
signal-quality | Signalstärke 0–100 |
ip-address | Aktuelle IP-Adresse |
modem-state | Modem-Power-State |
gps
| Feld | Beschreibung |
|---|---|
state | off / searching / fix-established / error |
latitude / longitude | Aktuelle Position (6 Nachkommastellen) |
altitude | Höhe in Metern |
speed | GPS-Geschwindigkeit |
course | Kurs in Grad |
timestamp | GPS-Zeitstempel (ISO-Format) |
alarm
| Feld | Werte |
|---|---|
status | disabled / disarmed / delay-armed / armed / level-1-triggered / level-2-triggered / seatbox-access. motion-service beobachtet dieses Feld und programmiert das BMX055-Chip-Profil reaktiv. |
motion
Wird vom motion-service (BMX055-Eigner) geschrieben. Heading-Felder werden mit jedem Magnetometer-Sample (5 Hz) aktualisiert.
| Feld | Beschreibung |
|---|---|
current-profile | idle / armed-awake / armed-hibernation / level1 / waiting – aktuell programmiertes Chip-Profil |
heading | 0–359 Grad, Ganzzahl, Fahrzeug-NED-Frame |
heading-deg | Tilt-kompensiert, EMA-geglättet |
heading-accuracy | Heuristische 1-σ-Schätzung in Grad |
heading-tilt | Neigungswinkel des Fahrzeugs gegenüber der Horizontalen |
initialized / streaming / polling-rate-hz | Service-Status |
last-interrupt-timestamp | Unix-ms des letzten Motion-Engine-Auslösens |
wake-cause | Wird einmalig beim Start gesetzt, falls INT_STATUS einen latched Bit zeigt (Wake-from-Hibernation-Indikator). Wird vom alarm-service gelesen + gelöscht. |
Pub/Sub-Channels, die motion-service veröffentlicht:
motion:sensors– 10 Hz JSON-IMU-Stream{accel, gyro, mag}motion:heading– 5 Hz JSONHeadingReadingmit roh + EMA-geglättetem Winkel, Genauigkeit, Tiltmotion:interrupt– JSON{type, timestamp, engine}Bewegungs-Edges;type:"wake-hibernation"für das Post-Resume-Signalmotion:ready– einmal beim Start ausgelöstmotion:rpc– Request-Channel für synchrone Methoden (prepare-hibernation,get-calibration,clear-latch,soft-reset)
settings
Persistente Konfiguration, verwaltet vom settings-service. Alle Felder sind per lsc settings get/set les- und schreibbar. Wichtige Keys:
| Key | Beschreibung |
|---|---|
alarm.enabled | true/false, Alarmanlage an/aus |
alarm.honk | true/false, Hupe während des Alarms |
alarm.duration | Alarmdauer in Sekunden |
updates.mdb.channel | OTA-Kanal: testing / nightly / stable |
updates.mdb.method | full oder delta |
dashboard.valhalla-url | Routing-Engine-Endpunkt |
dashboard.map.type | online / offline |
scooter.auto-standby-seconds | Timeout für automatisches Abschließen (0 = aus) |
pm.hibernation-timer | Verzögerungsbasierter Hibernate-Timeout in Sekunden (0 = aus; Minimum 300 s — Werte 1–299 werden auf 300 s angehoben). Standard 259200 (3 Tage). Der Timer läuft in jedem Ruhezustand und wird bei Aktivität zurückgesetzt. |
pm.default-state | Zielzustand im Leerlauf: run (wach bleiben) oder suspend (Auto-Sleep nach Vorlaufverzögerung) |
pm.scheduled-hibernate-enabled | true/false — aktiviert den Cron-basierten Hibernate-Zeitplan. Setzt einen gültigen pm.scheduled-hibernate-cron, eine Dauer > 0 in pm.scheduled-hibernate-duration und eine synchronisierte Uhr voraus, bevor überhaupt etwas ausgelöst wird. |
pm.scheduled-hibernate-cron | 5-stelliger Cron-Ausdruck (Minute Stunde Tag Monat Wochentag), der festlegt, wann der geplante Hibernate auslöst. Leer = deaktiviert. Auslösungen sind auf eine pro 15 Minuten begrenzt — pathologische Ausdrücke wie * * * * * oder */5 * * * * können den Roller nicht in einen Hibernate-Loop zwingen. Beispiel: 0 22 * * * (täglich um 22:00). |
pm.scheduled-hibernate-duration | Wake-by-Dauer beim Auslösen als Go-Duration-String (z. B. 8h, 30m). Aufwachen erfolgt zu Auslösezeit + Dauer (Wanduhr-Ziel). Ist der Roller bei Auslösung nicht im Stand-by, wird die Anforderung bis zum nächsten Stand-by aufgeschoben; das Ziel bleibt erhalten. |
pm.wake-timer-max-seconds | Sicherheitsobergrenze für die an den nRF52 gesendete Wake-Timer-Dauer bei hibernate-for (ad-hoc oder geplant). Höhere Anforderungen werden begrenzt. Minimum 60, Maximum/Standard 604800 (1 Woche). |
pm.wake-timer-ack-timeout | Wie lange pm-service auf die nRF52-Bestätigung des armierten Wake-Timers wartet, bevor der Hibernate abgebrochen wird. Go-Duration-String, Minimum 1 s, Standard 10s. |
ota
| Feld | Beschreibung |
|---|---|
status:mdb / status:dbc | idle / downloading / preparing / installing / pending-reboot / error |
download-progress:mdb | Download-Fortschritt 0–100 |
update-version:mdb | Zielversions-String |
error-message:mdb | Fehlerbeschreibung bei Status error |
sms
Vom modem-service geschriebener Kurzzustand für SMS. Die einzelnen Nachrichten liegen auf den Streams unter SMS-Streams.
| Feld | Beschreibung |
|---|---|
state | idle / sending / error |
last-received-from | Absender der zuletzt empfangenen Nachricht |
last-received-text | Text der zuletzt empfangenen Nachricht |
last-received-at | Zeitstempel (RFC 3339) der zuletzt empfangenen Nachricht |
last-sent-to | Empfänger der zuletzt erfolgreich gesendeten Nachricht |
last-sent-at | Zeitstempel (RFC 3339) des letzten erfolgreichen Versands |
unread-count | Seit dem Start des modem-service eingegangene Nachrichten. Nichts markiert sie als gelesen, es ist also ein Zähler und kein Posteingang. |
version:mdb / version:dbc
Wird vom version-service aus /etc/os-release geschrieben. Enthält Felder wie version_id, build_id, id.
Command-Queues
Services nehmen Befehle über Redis-Listen entgegen. Senden per LPUSH, Services lesen per BRPOP.
| Queue | Befehle |
|---|---|
scooter:state | lock, unlock, lock-hibernate |
scooter:seatbox | open |
scooter:power | run, suspend, hibernate, hibernate-manual, reboot |
scooter:blinker | left, right, both, off |
scooter:horn | on, off |
scooter:alarm | enable, disable, start:<seconds>, stop |
scooter:modem | enable, disable |
scooter:update:mdb / scooter:update:dbc | check-now |
scooter:bluetooth | advertising-start-with-whitelisting, advertising-restart-no-whitelisting, advertising-stop, delete-all-bonds |
scooter:sms | JSON-Sendeauftrag (siehe unten), anders als die einfachen String-Queues |
Beispiel:
redis-cli -h 192.168.7.1 LPUSH scooter:state unlock redis-cli -h 192.168.7.1 LPUSH scooter:alarm start:30
SMS senden
scooter:sms erwartet ein JSON-Objekt. id ist optional und kommt als request-id auf dem Stream sms:sent zurück, sodass sich Ergebnisse den eigenen Aufträgen zuordnen lassen.
redis-cli -h 192.168.7.1 LPUSH scooter:sms \
'{"id":"mein-token","to":"+491701234567","text":"Hallo vom Roller"}'
Pub/Sub
Sobald ein Service ein Hash-Feld aktualisiert, veröffentlicht er den geänderten Feldnamen auf einem Channel mit demselben Namen wie der Hash. Abonnent*innen lesen danach gezielt nur dieses eine Feld neu.
# Auf Änderungen am Vehicle-State subscriben redis-cli -h 192.168.7.1 SUBSCRIBE vehicle # Auf Akku-Updates subscriben redis-cli -h 192.168.7.1 SUBSCRIBE battery:0 battery:1
Als Message-Payload kommt der Feldname, der sich geändert hat (z.B. "state", "charge"). Empfänger*innen holen den neuen Wert mit HGET <hash> <field>.
Dieses Pattern ist in der redis-ipc-Bibliothek umgesetzt.
SMS-Streams
Einzelne Nachrichten passen nicht ins Hash-Muster, denn jede ist ein Ereignis und kein Zustand. Der modem-service hängt sie deshalb an zwei Streams an und kündigt jeden Eintrag als JSON auf einem gleichnamigen Channel an.
| Stream / Channel | Inhalt |
|---|---|
sms:received | Ein Eintrag pro eingehender Nachricht: id, from, text, timestamp |
sms:sent | Ein Eintrag pro abgeschlossenem Sendeversuch: id, request-id, to, text, outcome (sent oder error), error, timestamp |
# Anzeigen, was noch gepuffert ist redis-cli -h 192.168.7.1 XRANGE sms:received - + # Oder JSON-Pushes live abonnieren redis-cli -h 192.168.7.1 SUBSCRIBE sms:received sms:sent
Beide Streams sind auf 100 Einträge begrenzt. Der Datenspeicher überlebt keinen Neustart, das Limit begrenzt also den Speicherverbrauch und keine Historie: nach einem Neustart ist ohnehin alles weg. Das XADD ist der Zustellpunkt, eine Nachricht auf sms:received wird also nicht doppelt zugestellt.
Die Zustellung über LTE hängt netzseitig an einer SGs-Assoziation, die ablaufen kann, während das Modem nur Daten überträgt. Der modem-service kann sie mit regelmäßigen Selbstanrufen wachhalten, das ist aber standardmäßig aus. Bei Bedarf mit
-sms-keepalive einschalten, wenn nach längerer Ruhe keine Nachrichten mehr ankommen.