Bluetooth-Sensoren (BLE): Den Weg für eine externe Integration ebnen

Nach einem Austausch mit dem Erfinder von Theengs / OpenMQTTGateway wurde eine Lücke identifiziert: Gladys hat zwar eine Bluetooth-Integration, aber sie deckt nur eine Handvoll Geräte ab — während das Ökosystem der BLE-Sensoren (Temperatur, Luftfeuchtigkeit, Pflanzen usw.: Xiaomi, SwitchBot, RuuviTag…) riesig ist und Projekte wie Theengs Hunderte davon decodieren können.

Für mich muss das über eine externe Integration laufen, nicht über Code im Core. Aber heute gibt der Framework für externe Integrationen keinen Zugriff auf das Bluetooth der Maschine, und aus gutem Grund: Im Gegensatz zu einem Zigbee-Stick (ein einfaches USB-Gerät, das im Container eingebunden werden kann), bedeutet das Gewähren von Bluetooth-Zugriff auf einen Container, ihm sehr weitreichende Netzwerkprivilegien auf der Maschine zu geben, was mit dem Sicherheitsmodell des Stores unvereinbar ist (nicht überprüfte Drittanbieter-Integrationen, die in einem Klick installierbar sind).

Die in Betracht gezogene Lösung: ein Bluetooth-Mediator-Zugriff, nach demselben Modell wie die bereits implementierte Netzwerkentdeckung, der Core hört das Radio ab und leitet die Rohdaten weiter, die Integration decodiert sie und veröffentlicht Sensoren und Zustände über die bestehenden APIs. Der Adapter bleibt unter der Kontrolle des Cores, was ohnehin unverzichtbar sein wird, wenn es eines Tages um Matter/Thread-Commissioning über BLE geht.

Anmerkung: Für diejenigen, die ESP32-Gateways mit OpenMQTTGateway verwenden, ist eine externe Integration bereits heute über MQTT möglich, ohne dass am Framework etwas geändert werden muss.

Das Thema hier ist die Nutzung des Bluetooth-Adapters der Maschine, auf der Gladys läuft.

Hallo,

Wenn der Zugriff auf Bluetooth möglich ist, sollten wir in der Lage sein, die Frames zu decodieren und Gladys mit allen diesen Geräten lesbar kompatibel zu machen.

Hier ist, was ein Decoder wie Theengs von der API benötigt:

1. Die Integration steuert den Scan — der Core führt aus und arbitriert. Gleiche Philosophie wie scanNetwork(): Die Integration fordert ein begrenztes Scan-Fenster an, z. B. gladys.scanBluetooth({ mode, durationSeconds, filters }), und der Core behält die Kontrolle über den Adapter. Zwei Nuancen im Vergleich zu scanNetwork:

  • Die Frames müssen während des Fensters gestreamt werden (Callback im laufenden Betrieb), nicht nur am Ende in einem Block ausgegeben, da die Latenz für die Zustände zählt;
  • Das Fenster muss verlängerbar sein (Mietmodell): Die Integration entscheidet über den Takt — intensiv während einer Entdeckung, reduzierter Duty Cycle im Dauerbetrieb (z. B. 10 Sekunden Scan alle 60 Sekunden), Stopp, wenn der Benutzer deaktiviert.

Der Core bleibt der alleinige Schiedsrichter: Maximale Dauer pro Fenster, Kontingente, Verteilung zwischen Integrationen und sofortige Vorrangstellung, wenn Matter/Thread das Radio benötigt.

2. Minimaler Frame-Inhalt. Zum Decodieren benötigt Theengs:

  • mac (+ Adresstyp öffentlich/zufällig) — dies ist die stabile Kennung des Geräts
  • rssi
  • name (lokale Bezeichnung) falls vorhanden
  • manufacturerdata (Bytes, Hex oder Base64)
  • servicedata + servicedatauuid
  • angekündigte serviceUuids
  • ein Zeitstempel und die Angabe, ob es sich um einen Advertising-Frame oder einen Scan-Response handelt

Ein rohes Feld (payload_base64 der AD-Strukturen, konsistent mit scanNetwork) zusätzlich zu den geparsten Feldern wäre ideal: Es deckt exotische Fälle ab, ohne die Parsing-Seite des Cores festzulegen.

3. Passiver und aktiver Scan, je nach Anfrage. Einige weit verbreitete Sensoren stellen ihre Daten nur in der Scan-Response bereit (daher ist ein aktiver Scan erforderlich). Der mode ist ein Parameter der Scan-Anfrage; das Manifest erklärt die maximal zulässige Kapazität (z. B. "bluetooth": { "modes": ["passive", "active"] }), die der Benutzer der Installation gewährt.

4. Filterung auf Core-Ebene, parametrisiert durch die Anfrage. Optional, aber wertvoll, um den WebSocket nicht zu überlasten: Filter nach MAC-Präfix, manufacturer_id oder service_uuid, die in den Scan-Optionen angegeben werden, und ein Throttle pro MAC (z. B. max. 1 Frame/MAC/Sekunde, Sensoren wiederholen denselben Frame in Salven).

5. Verwaltung der Adapter: auf Core-Ebene, alleiniger Eigentümer. Dies ist der Punkt, der das Mediator-Modell wirklich über einen direkten Zugriff stellt:

  • Der Core inventarisiert die Adapter (hci0, USB-Dongles…), hält sie auf dem neuesten Stand (Hotplug), überwacht ihre Gesundheit und setzt sie zurück, falls sie blockieren, günstige BLE-Adapter frieren regelmäßig ein, ein zentraler Watchdog profitiert allen;
  • Der Core ist der alleinige Eigentümer jedes Adapters und multiplexiert alle Verbraucher: Bluetooth-Core-Service (GATT/Präsenz), Matter/Thread-Commissioning und Scan-Fenster der Integrationen, keine Eigentumsstreitigkeiten zwischen Prozessen mehr;
  • Benutzerseite: Wenn mehrere Adapter vorhanden sind, ist es in der Core-Konfiguration, dass er die Rollen zuweist (z. B. hci0 für Matter reserviert, USB-Dongle für den Scan der Integrationen);
  • Integrationsseite: niemals ein /dev-Pfad oder ein physischer Adaptername, höchstens eine optionale logische Kennung in den Scan-Optionen, wenn der Benutzer mehrere Adapter zugewiesen hat. Die Integration fordert „einen Scan“ an, nicht „Adapter X“.

Bonus für die Zukunft: Mehrere Adapter, die dem Scan zugewiesen sind, bedeuten mehrere Antennen, bessere Abdeckung — und die API muss sich nicht ändern, der Core aggregiert die Frames.

6. Benutzerzustimmung. Wie bei den bestehenden Materialklassen: Das Abhören von BLE offenbart die Anwesenheit von Personen (Telefone, Wearables) — ein Autorisierungsbildschirm bei der Installation, der sich von anderen Berechtigungen unterscheidet, scheint die richtige Granularität zu sein.

7. Außerhalb des Umfangs für eine v1 des Relais (aus unserer Sicht): Keine GATT-Verbindung oder Schreibvorgänge von den Integrationen aus, das alleinige Advertising-Lesevorgang deckt bereits die überwiegende Mehrheit der Sensoren ab und hält das Sicherheitsmodell einfach.

Einige Ressourcen:

https://www.npmjs.com/package/theengs-decoder

Hallo zusammen!

Dieses Thema ist nun in Entwicklung.

Ein Pull Request wurde eröffnet, um das Streaming von BLE-Werbungen (Bluetooth-Sensoren) zu spezifizieren:

Zögert nicht, dem PR zu folgen, zu testen (optional, vor allem bei kleinen Anfragen) und euer Feedback hier zu hinterlassen, falls nötig.

@1technophile Ich habe eine Spezifikation mit Fable 5 vorgeschlagen, was hältst du davon? :slight_smile:

@pierre-gilles Wird das den Weg für eine externe OTBR-Integration (Open Thread Border Router) ebnen?

Danke, einige Kommentare, aber nichts Blockierendes

Danke für dein Feedback @1technophile!

Nein, das glaube ich nicht!