====== Bluetooth-Verbindung mit Linux ======
//Diese Anleitung beschreibt, wie  der mBot-Roboter per **BLE (Bluetooth Low Energy)**  unter Ubuntu angesprochen werden kann. Dabei wird ein Python-Skript (''makeblock_test.py'') verwendet, das testweise die LEDs des mBots schalten kann.
//
  * Voraussetzungen
          * Installation und Konfiguration der benötigten Pakete
  * ''bluetoothctrl''
          * Umgang mit dem wichtigen Tool zur Kontrolle der angeschlossenen Bluetoothgeräte.
  * Testen
          * Testen (hier in Python) der Verbindung und Steuern des mBot-Roboters.
====== Voraussetzungen ======
++++ Installation und Konfiguration der benötigten Pakete |
Systemvoraussetzungen & benötigte Pakete 
Getestet wurde mit folgender Umgebung:
  * **Ubuntu** (getestet mit 20.04 & 22.04, sollte auch auf anderen Versionen laufen)
  * **Python 3.11+** (Empfohlen: Anaconda oder System-Python)
  * **Bluetooth-Adapter mit BLE-Unterstützung**
          * USB-BT500 ASUS  (Dieser Stand stand zum Testen zur Verfügung)
==== Notwendige Pakete installieren ====
Führen Sie folgende Befehle aus, um alle benötigten Systempakete zu installieren:
sudo apt update
sudo apt install bluetooth bluez bluez-tools rfkill libbluetooth-dev
 
----
==== Bluetooth einrichten & Berechtigungen setzen ====
Damit Bluetooth verwendet werden kann muss der Benutzer in die **''bluetooth''-Gruppe** aufgenommen werden:
sudo usermod -aG bluetooth $USER
newgrp bluetooth  # Änderungen sofort anwenden
Starten Sie anschließend den **Bluetooth-Stack neu**:
sudo systemctl restart bluetooth
sudo rfkill unblock bluetooth
Ältere Ubuntu-Distributionen benötigen möglicherweise einen Link, falls der USB-BT500 ASUS nicht erkannt wird.
$ cd /usr/lib/firmware/rtl_bt
$ sudo ln -s rtl8761b_fw.bin rtl8761bu_fw.bin
☛ https://forums.linuxmint.com/viewtopic.php?t=377733
----
===== Python  =====
Damit BLE-Geräte gesteuert werden können, wird ''bleak'' benötigt.
==== Installation mit ''pip'' (System-Python oder venv) ====
Falls ohne Conda gearbeitet wird:
pip install bleak
----
++++
====== Tool: bluetoothctl   ======
++++ Umgang mit dem wichtigen Tool zur Kontrolle der angeschlossenen Bluetoothgeräte.|
Im diesem Abschnitt wird das Tool ''bluetoothctl'' vorgestellt, mit dem die Bluetooth-Schnittstelle verwaltet werden kann. Außerdem werden einige nützliche Kommandos erläutert, um eine erfolgreiche Verbindung zum mBot herzustellen. 
===== Bluetooth-Befehle & Erklärungen =====
Hauptfunktionen von bluetoothctl
  * Aktivieren und Deaktivieren von Bluetooth
  * Suchen und Verbinden mit Bluetooth-Geräten
  * Koppeln und Entkoppeln von Geräten
  * Anzeigen und Verwalten von gekoppelten Geräten
  * Ändern von Bluetooth-Einstellungen
^ **Befehl**                  ^ **Beschreibung**                                               ^
| ''bluetoothctl''             | Startet das Bluetooth-Management-Tool                           |
| ''scan on ''                 | Sucht nach BLE-Geräten in der Umgebung                         |
| ''scan off''                 | Stoppt die Suche nach BLE-Geräten (wichtig für Verbindungsaufbau)|
|''devices''                  | Zeigt eine Liste aller erkannten Bluetooth-Geräte              |
|''info ''               | Zeigt detaillierte Informationen zu einem Gerät                |
| ''trust ''              | Markiert das Gerät als vertrauenswürdig                       |
| ''connect ''            | Verbindet sich mit dem angegebenen Gerät                      |
| ''disconnect ''         | Trennt die Verbindung zum Gerät                               |
| ''remove ''             | Entfernt das Gerät aus der Liste bekannter Geräte             |
| ''sudo systemctl restart bluetooth'' | Startet den Bluetooth-Dienst neu (bei Verbindungsproblemen) |
  * mbot Bluetooth Modul blinkt → keine Verbindung!
  * mbot Bluetool Modul leuchtet Dauerhaft →  Verbindung!
===== Bluetooth-Interface  =====
bluetoothctl
Falls Sie bereits in ''bluetoothctl'' sind, sehen Sie eine Eingabezeile wie:
[bluetooth]#
===== Scannen nach BLE-Geräten =====
scan on
Lassen Sie den Scan 10–15 Sekunden laufen, bis Ihr mBot erscheint.  
Er sollte eine MAC-Adresse in diesem Format haben: ''10:A5:62:22:CA:C4''.
Da manche BLE-Geräte keine Verbindung erlauben, während sie noch gescannt werden, sollte der Scan zuvor mit scan off beendet werden, falls scan on verwendet wurde.
scan off # scan wieder beenden!
Alternativ kann mit dem Befehl ''devices'' eine Liste der Geräte (und MAC-Adressen) angezeigt werden.
[bluetooth]# devices
Device 59:65:C3:57:CC:EC 59-65-C3-57-CC-EC
Device 25:81:AA:74:75:85 25-81-AA-74-75-85
Device 10:A5:62:22:CA:C4 Makeblock_LE10a56222cac4
[DEL] Device 25:81:AA:74:75:85 25-81-AA-74-75-85
[bluetooth]# 
===== Wichtige Befehle =====
==== Verbindung vertrauen und verbinden ====
Ersetzen Sie die MAC-Adresse mit der Ihres mBots:
trust 10:A5:62:22:CA:C4
connect 10:A5:62:22:CA:C4
Falls die Verbindung klappt, sehen Sie:
[CHG] Device 10:A5:62:22:CA:C4 Connected: yes
Connection successful
Falls die Verbindung fehlschlägt,  Bluetooth-Dienst neu starten:
sudo systemctl restart bluetooth
==== Verbindung trennen und entfernen ====
Falls Ihr mBot **direkt nach dem Verbinden mit Ubuntu verbunden bleibt**, trennen Sie ihn:
disconnect 10:A5:62:22:CA:C4
remove 10:A5:62:22:CA:C4
Mit ''info MAC'' können Informationen abgerufen werden!
**Hinweis:**
Der mBot sollte __nur__ mit dem Python-Skript verbunden sein, nicht dauerhaft mit Ubuntu!
----
++++
====== Testen ======
**Um die Skripte zu testen, muss die MAC-Adresse des Makeblock-Bluetooth-Moduls bekannt sein!**
Sie ist im Skript durch die von uns verwendete //(10:A5:62:22:CA:C4)// zu ersetzen. Ansonsten muss das Skript nicht angepasst werden.
Die Bereiche, die im Skript geändert werden müssen, sind durch
 # TODO ADJUST START
 
und
# TODO ADJUST END
 
gekennzeichnet.
Die folgende Ausgabe von ''bluetoothctl'' zeigt, dass alle Voraussetzungen für das Testen mit Python erfüllt sind!
[bluetooth]# info 10:A5:62:22:CA:C4
Device 10:A5:62:22:CA:C4 (public)
 Name: Makeblock_LE10a56222cac4
 Alias: Makeblock_LE10a56222cac4
 Paired: no
 Trusted: yes
 Blocked: no
 Connected: no
 LegacyPairing: no
 UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
 UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
 UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
 UUID: Vendor specific           (00006287-3c17-d293-8e48-14fe2e4da212)
 UUID: Vendor specific           (0000d0ff-3c17-d293-8e48-14fe2e4da212)
 UUID: Unknown                   (0000ffe1-0000-1000-8000-00805f9b34fb)
 UUID: Unknown                   (0000ffe4-0000-1000-8000-00805f9b34fb)
 Modalias: bluetooth:v005Dp0001d0003
  * ✅ Connected: no → Der mBot ist nicht dauerhaft mit Ubuntu verbunden → Gut!
  * ✅ Trusted: yes → Der mBot wurde als vertrauenswürdig eingestuft → Richtig konfiguriert!
  * ✅ Paired: no → Der mBot wurde nicht gekoppelt (BLE braucht keine Kopplung)
  * ✅ Liste der UUIDs → Zeigt die verfügbaren GATT-Services und Characteristics des Geräts.
===== BLE-Scanner =====
Dieses Skript prüft, ob ''bleak'' den mBot erkennt.
import asyncio
from bleak import BleakScanner
async def scan():
    print("Scanne nach BLE-Geräten...")
    devices = await BleakScanner.discover()
    for device in devices:
        print(f"Gefunden: {device.name} - {device.address}")
asyncio.run(scan())
Falls der mBot erkannt wird, ist alles korrekt eingerichtet!
----
===== mbot steuern =====
Dieses Script steuert  mit einfachen Kommandos die LEDs des mBot.
import asyncio
from bleak import BleakClient
# TODO ADJUST START
#  Makeblock BLE-Adresse hier eintragen
device_address = "10:A5:62:22:CA:C4"
# TODO_ADJUST END
WRITE_CHAR_UUID = "0000ffe3-0000-1000-8000-00805f9b34fb"
async def send_char(client, char):
    """Sendet ein einzelnes Zeichen über BLE"""
    try:
        # Konvertiere Zeichen in Byte
        data = bytearray([ord(char)])  
        await client.write_gatt_char(WRITE_CHAR_UUID, data)
        print(f"Gesendet: {char}")
    except Exception as e:
        print(f"Fehler beim Senden von '{char}': {e}")
async def main():
    """Verbindet sich mit dem mBot und sendet Befehle"""
    try:
        async with BleakClient(device_address) as client:
            if await client.is_connected():
                print(f"Verbunden mit {device_address}")
                while True:
                    user_input = input("'r', 'g', 'b', '0' zum Senden. 'q' zum Beenden: ")
                    if user_input == 'q':
                        print("Programm beendet.")
                        break  # Beende das Programm
                    elif user_input in ['r', 'g', 'b', '0']:
                        await send_char(client, user_input)  # senden
                    else:
                        print("Ungültige Eingabe!")
    except Exception as e:
        print(f"Verbindungsfehler: {e}")
asyncio.run(main())