USS Enterprise in Loxone einbinden

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • MarkusCosi
    LoxBus Spammer
    • 28.09.2023
    • 314

    #1

    USS Enterprise in Loxone einbinden

    ..vllt. hat der ein oder andere ja auch die USS Enterprise von Playmobil zuhause.... bekanntlich lässt sich diese per Android oder iOS App steuern, z.B. im "Kommando"-Modus, um Licht und Sound-Effekte abzuspielen. Mit einem ESP32 Modul und den Infos zu den Bluetooth-Kennungen kann man die Licht & Sound-Effekte der Enterprise auch über http-Befehle in Loxone einbinden.

    Ich habe dazu folgendes ESP32 Modul benutzt: ESP32-D0WD-V3 (revision v3.1) / diymore ESP32 NodeMCU ESP32 WROOM 32D - development board CH340.
    Zusätzlich benötigt ihr nur noch die MAC Adresse eurer Enterprise, z.B. herauszufinden über Wireshark (ggf. auch über BLE Scanner App?), und den Code unten für den ESP32. Danach in Loxone http-get Befehle triggern, z.B. mit http://192.168.1.XXX/M1 (XXX=vergebene lokale IP, herausfinden am Router!).

    Ich habe die BLE-Befehle der iPhone App an die Enterprise über iPhone Bluetooth Logging in Erfahrung gebracht (nach Aktivierung des Loggings die App benutzt und die Befehle der Reihe nach ausgeführt), und zwar so wie hier beschrieben per Wireshark und dem Filter: bluetooth.dst == ac:XX:XX:26:c5:22. Hier muss man die passende MAC Adresse für euere Enterprise in Wireshark herausfinden (suche nach: "TexasInstrum_26:c5:22", oder nach Timestamp die entsprechenden Befehle im BT Protokoll wiederfinden) um übersichtlich alle Befehle (=Values) an die Enterprise gelistet zu bekommen. Man bekommt so die einzelnen Befehle heraus um die entsprechenden Aktionen zu triggern. Das habe ich bereits gemacht und findet sich unter im Code im byte-Array PmUSSECMDs wieder!

    Schnell konnte ich so (geht auch über BLE scanner Apps am Smartphone) den entsprechenden BLE Service UUID und die Charcteristic UUID herausfinden:
    [Destination Device Name: Pm_USSE_6C522] ← hierunter ist die Enterprise in BLE Scanner Apps schnell zu finden.
    [Service UUID: bc2f4cc6aaef43519034d66268e328f0]
    [UUID: 06d1e5e779ad4a718faa373789f7d93c]

    über eine iPhone App wie z.B. "BLE Scanner" (dort: connect to "Pm_USSE_6C522" → Custom Service → Custom Characteristic → click "W" symbol → Hex → e.g.: aa0701ffff) oder aber am Mac über eine App wie "LightBlue" (dort: connect to "Pm_USSE_6C522" → USSE Command (="Characteristic user description") → "Write new value") kann man die Befehle (=Values) auch vorher mal testen.

    Der nächste Schritt war die Verbindung zur Enterprise analog zu meinem Vorgehen hier: link, d.h. unter Nutzung der "BLEDevice.h"-Library. (siehe code anbei)
    Außerdem läuft dann auf dem ESP32 ein Server über die Bibliotheken: "WiFi.h" / "WiFiClient.h" / "HTTPClient.h", sodass das Modul die passenden BLE Befehle auf http-get Befehl hin sendet...

    Anwendungsfälle:
    • Kopplung des "Roter Alarm"-Sounds an die Alarm-Anlage
    • Lichter der Enterprise an BWM Koppeln...

    Viel Spaß damit!

    Code:
    // Playmobile USS Enterprise
    #include <WiFi.h> //Wifi support
    #include <WiFiClient.h> //Wifi support
    #include <HTTPClient.h> //Wifi server support
    #include "BLEDevice.h" //BLE support
    
    //On-chip LED GPIO (depends on used ESP32 board)
    int LED_BUILTIN = 2;
    const byte LED_Blue = 32;
    const byte LED_White = 33;
    const byte LED_Red = 27;
    int LED_BlueStatic = 0;
    
    //Wifi SSID and password
    const char* ssid = "YourSSID";
    const char* password = "YourPW";
    unsigned long previousMillis = 0;
    unsigned long timeoutTime = 30000; //timeout for Wifi-Connection
    unsigned long previousMillisS = 0;
    const long timeoutTimeS = 1000; // Define timeout for Server connection
    WiFiServer server(80);
    
    //BLE UUIDs: The pattern is 8-4-4-4-12
    #define EnterpriseBLEAddress "ac:XX:XX:26:c5:22"
    // The remote service we wish to connect to: Pm_USSE_6C522 (Playmobil USS Enterprise)
    static BLEUUID serviceUUID("bc2f4cc6-aaef-4351-9034-d66268e328f0");
    // The characteristic of the remote service we are interested in: "USSE Command"
    static BLEUUID charUUID("06d1e5e7-79ad-4a71-8faa-373789f7d93c");
    static BLERemoteCharacteristic* pRemoteCharacteristic;
    //variable holding connection status
    bool BLEConnectionStatus;
    
    //define commands ("Values") sniffed from Playmobil Enterprise iPhone APP
    static byte PmUSSECMDs[25][5] = {
    {0xaa, 0x07, 0x01, 0xff, 0xff}, // CMD 1 / Warp: aa0701ffff
    {0xaa, 0x07, 0x02, 0x00, 0xff}, // CMD 2 / Alarm: aa070200ff
    {0xaa, 0x07, 0x03, 0x00, 0xff}, // CMD 3 / Torpedo: aa070300ff
    {0xaa, 0x08, 0x07, 0xc8, 0xff}, // CMD 4 / sound Alarm: aa0807c8ff
    {0xaa, 0x08, 0x05, 0xc8, 0xff}, // CMD 5 / sound Torpedo: aa0805c8ff
    {0xaa, 0x08, 0x02, 0xc8, 0xff}, // CMD 6 / sound Pfeife: aa0802c8ff
    {0xaa, 0x08, 0x08, 0xc8, 0xff}, // CMD 7 / sound Live long and Prosper: aa0808c8ff
    {0xaa, 0x08, 0x06, 0xc8, 0xff}, // CMD 8 / sound Scotty James to Enterprise: aa0806c8ff
    {0xaa, 0x08, 0x0b, 0xc8, 0xff}, // CMD 9 / sound Dematerialisieren: aa080bc8ff
    {0xaa, 0x08, 0x01, 0xc8, 0xff}, // CMD 10 / sound Astrogator starten: aa0801c8ff
    {0xaa, 0x04, 0x07, 0xc8, 0xff}, // CMD 11 / lights: Warp Gondeln: aa0407c8ff
    {0xaa, 0x05, 0x07, 0xc8, 0xff}, // CMD 12 / lights: Go to Warp: aa0507c8ff
    {0xaa, 0x04, 0x03, 0xc8, 0xff}, // CMD 13 / lights: Torpedo: aa0403c8ff
    {0xaa, 0x05, 0x01, 0xc8, 0xff}, // CMD 14 / lights: Torpedo Twice: aa0501c8ff
    {0xaa, 0x03, 0xff, 0x00, 0xff}, // CMD 15 / Vol 100: aa03ff00ff
    {0xaa, 0x03, 0x83, 0x00, 0xff}, // CMD 16 / Vol 50: aa038300ff
    {0xaa, 0x03, 0x80, 0x00, 0xff}, // CMD 17 / Vol 30: aa038000ff
    {0xaa, 0x03, 0x00, 0x00, 0xff}, // CMD 18 / Vol 0: aa030000ff
    {0xaa, 0x07, 0x04, 0x00, 0xff}, // CMD 19 / Alles AUS: aa070400ff
    {0xaa, 0x08, 0x09, 0xc8, 0xff}, // CMD 20 / sound: BeepBeep aa0809c8ff (NEU Jul2025)
    {0xaa, 0x08, 0x03, 0xc8, 0xff}, // CMD 21 / sound: Brückenambiente aa0803c8ff (NEU Jul2025)
    {0xaa, 0x08, 0x04, 0xc8, 0xff}, // CMD 22 / sound: Dilithiumkern entfernt inkl. Alarm aa0804c8ff (NEU Jul2025)
    {0xaa, 0x04, 0x01, 0xc8, 0xff}, // CMD 23 / lights: Konsode (Brücke): aa0401c8ff (NEU Jul2025)
    {0xaa, 0x04, 0x02, 0xc8, 0xff}, // CMD 24 / lights: roter Alarm (Brücke): aa0402c8ff (NEU Jul2025)
    {0xaa, 0x04, 0x06, 0xc8, 0xff} // CMD 25 / lights: Dilithiumkern (Maschinenraum): aa0406c8ff (NEU Jul2025)
    };
    
    WiFiClient espClient;
    // Standard Arduino function which is called once when the device first starts up
    void setup() {
    // Setup for Serial Monitor (when connected to Arduino IDE: Tools -> Serial Monitor)
    Serial.begin(9600);
    while(!Serial) {
    delay(10);
    }
    // Initialize digital pin LED_BUILTIN, & the external LED pins (LED_Blue, LED_White) as an output.
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(LED_Blue, OUTPUT);
    pinMode(LED_White, OUTPUT);
    pinMode(LED_Red, OUTPUT);
    //status LED shows light
    digitalWrite(LED_White, HIGH); // turn the external status LED on (HIGH is the voltage level)
    //Alarm LED (red) off by default
    digitalWrite(LED_Red, LOW); // turn the external status LED on (HIGH is the voltage level)
    //connect to Pm_USSE_6C522 (Playmobil USS Enterprise)
    BLEDevice::init("");
    BLEClient* pClient = BLEDevice::createClient();
    Serial.println("\nTrying to connect to Pm_USSE_6C522");
    //BLE address of Pm_USSE_6C522 (Playmobil USS Enterprise)
    if (pClient->connect(BLEAddress(EnterpriseBLEAddress))) {
    Serial.println("Connected!");
    BlinkLED();BlinkLED();
    Serial.println("\nTrying to connect to BLE-Service");
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
    Serial.println("Failed to get service");
    return;
    } else Serial.println("Got service");
    Serial.println("\nTrying to connect to BLE-Characteristic of Service");
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
    Serial.println("Failed to get characteristic");
    return;
    } else Serial.println("Got characteristic");
    } else Serial.println("Failed to connect");
    Serial.println("\nPrint Status:");
    BLEConnectionStatus = pClient->isConnected();
    Serial.println(BLEConnectionStatus);
    // Connect to WiFi
    Serial.println("\nConnecting to WiFi");
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while(WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(500);
    }
    Serial.print("\nConnected to the WiFi network: ");
    Serial.print(String(ssid));
    Serial.print(" | local ESP32 IP: ");
    Serial.print(WiFi.localIP());
    Serial.print(" | RSSI: ");
    Serial.println(WiFi.RSSI());
    //start server to allow control via http commands
    server.begin();
    // Blink LED on Chip once on Startup
    BlinkLED();BlinkLED();BlinkLED();
    }
    
    // Blink LED on Chip
    void BlinkLED() {
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    if (LED_BlueStatic == 0) {
    digitalWrite(LED_Blue, HIGH); // turn the external LED on (HIGH is the voltage level)
    }
    delay(100); // LED on for 100msec
    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
    if (LED_BlueStatic == 0) {
    digitalWrite(LED_Blue, LOW); // turn the external LED off
    }
    delay(100); // wait / off for 100msec
    }
    
    // Standard Arduino function that is called in an endless loop after setup
    void loop() {
    unsigned long currentMillis = millis(); //works for ca. 50 days before reset to 0
    unsigned long currentMillisS = millis(); //works for ca. 50 days before reset to 0
    // if WiFi is down, try reconnecting every timeoutTime seconds
    if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >= timeoutTime)) {
    Serial.print(millis());
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.reconnect();
    Serial.print("\nConnected to the WiFi network: ");
    Serial.print(String(ssid));
    Serial.print(" | local ESP32 IP: ");
    Serial.print(WiFi.localIP());
    Serial.print(" | RSSI: ");
    Serial.println(WiFi.RSSI());
    previousMillis = currentMillis;
    }
    if (currentMillis - previousMillis < 0) {
    previousMillis = currentMillis;
    }
    //get restart command from external http command to server
    WiFiClient client = server.available();
    if (client) {
    currentMillisS = millis();
    previousMillisS = currentMillisS;
    Serial.println("New Client");
    String currentLine = "";
    while (client.connected() && (currentMillisS - previousMillisS <= timeoutTimeS)) {
    currentMillisS = millis();
    if (client.available()) {
    char c = client.read();
    Serial.write(c);
    if (c == '\n') {
    if (currentLine.length() == 0) {
    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
    // and a content-type so the client knows what's coming, then a blank line:
    client.println("HTTP/1.1 200 OK");
    client.println("Content-type:text/html");
    //client.println("Connection: close");
    client.println();
    //create the buttons
    client.print("Effekte: <a href=\"/E1\">Warp</a><br>");
    client.print("Effekte: <a href=\"/E2\">Alarm</a><br>");
    client.print("Effekte: <a href=\"/E3\">Torpedo</a><br><br>");
    client.print("Sound: <a href=\"/S0\">Brueckenambiente</a><br>");
    client.print("Sound: <a href=\"/S1\">Alarm</a><br>");
    client.print("Sound: <a href=\"/S2\">Torpedo</a><br>");
    client.print("Sound: <a href=\"/S3\">Pfeife</a><br>");
    client.print("Sound: <a href=\"/S4\">Live Long and Prosper</a><br>");
    client.print("Sound: <a href=\"/S5\">Scotty James to Enterprise</a><br>");
    client.print("Sound: <a href=\"/S6\">Dematerialisieren</a><br>");
    client.print("Sound: <a href=\"/S7\">Astrogator starten</a><br>");
    client.print("Sound: <a href=\"/S8\">Beep Beep</a><br>");
    client.print("Sound: <a href=\"/S9\">Dilithiumkern entfernt (inkl. Alarm)</a><br><br>");
    client.print("Lights: <a href=\"/L1\">Warp Gondeln</a><br>");
    client.print("Lights: <a href=\"/L2\">Go to Warp</a><br>");
    client.print("Lights: <a href=\"/L3\">Torpedo Full</a><br>");
    client.print("Lights: <a href=\"/L4\">Torpedo Twice</a><br>");
    client.print("Lights: <a href=\"/L5\">Konsole (Bruecke)</a><br>");
    client.print("Lights: <a href=\"/L6\">Roter Alarm (Bruecke)</a><br>");
    client.print("Lights: <a href=\"/L7\">Dilithiumkern (Maschinenraum)</a><br><br>");
    client.print("Volume: <a href=\"/v1\">100%</a><br>");
    client.print("Volume: <a href=\"/v2\">50%</a><br>");
    client.print("Volume: <a href=\"/v3\">30%</a><br>");
    client.print("Volume: <a href=\"/v4\">0%</a><br><br>");
    client.print("Enterprise: <a href=\"/x\">AUS</a><br><br>");
    client.print("ESP32 Modul: <a href=\"/T\">Blink!</a><br>");
    client.print("ESP32 Modul: <a href=\"/SOff\">Status LED Off</a><br>");
    client.print("ESP32 Modul: <a href=\"/SOn\">Status LED On</a><br>");
    client.print("ESP32 Modul: <a href=\"/B0\">Blue LED: Blink on BLE CMDs</a><br>");
    client.print("ESP32 Modul: <a href=\"/B1\">Blue LED: keep ON</a><br>");
    client.print("ESP32 Modul: <a href=\"/AOff\">RED LED: Off</a><br>");
    client.print("ESP32 Modul: <a href=\"/AOn\">RED LED: On</a><br><br>");
    client.print("ESP32 Modul: <a href=\"/d\">deep sleep</a><br>");
    client.print("ESP32 Modul: <a href=\"/R\">restart</a><br>");
    // The HTTP response ends with another blank line:
    client.println();
    // break out of the while loop:
    break;
    } else {
    currentLine = "";
    }
    } else if (c != '\r') {
    currentLine += c;
    }
    // Execute commands
    if (currentLine.endsWith("GET /T")) {
    Serial.println(" command received to Blink ESP32 Module");
    BlinkLED();BlinkLED();BlinkLED();
    }
    if (currentLine.endsWith("GET /R")) {
    Serial.println(" command received to restart ESP32 Module");
    BlinkLED();BlinkLED();BlinkLED();
    ESP.restart();
    }
    if (currentLine.endsWith("GET /E1")) {
    Serial.println(" command received to send BLE-command 1 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[0],sizeof(PmUSSECMDs[0]));
    }
    if (currentLine.endsWith("GET /E2")) {
    Serial.println(" command received to send BLE-command 2 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[1],sizeof(PmUSSECMDs[1]));
    }
    if (currentLine.endsWith("GET /E3")) {
    Serial.println(" command received to send BLE-command 3 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[2],sizeof(PmUSSECMDs[2]));
    }
    if (currentLine.endsWith("GET /S0")) {
    Serial.println(" command received to send BLE-command 21 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[20],sizeof(PmUSSECMDs[20]));
    }
    if (currentLine.endsWith("GET /S1")) {
    Serial.println(" command received to send BLE-command 4 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[3],sizeof(PmUSSECMDs[3]));
    }
    if (currentLine.endsWith("GET /S2")) {
    Serial.println(" command received to send BLE-command 5 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[4],sizeof(PmUSSECMDs[4]));
    }
    if (currentLine.endsWith("GET /S3")) {
    Serial.println(" command received to send BLE-command 6 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[5],sizeof(PmUSSECMDs[5]));
    }
    if (currentLine.endsWith("GET /S4")) {
    Serial.println(" command received to send BLE-command 7 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[6],sizeof(PmUSSECMDs[6]));
    }
    if (currentLine.endsWith("GET /S5")) {
    Serial.println(" command received to send BLE-command 8 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[7],sizeof(PmUSSECMDs[7]));
    }
    if (currentLine.endsWith("GET /S6")) {
    Serial.println(" command received to send BLE-command 9 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[8],sizeof(PmUSSECMDs[8]));
    }
    if (currentLine.endsWith("GET /S7")) {
    Serial.println(" command received to send BLE-command 10 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[9],sizeof(PmUSSECMDs[9]));
    }
    if (currentLine.endsWith("GET /S8")) {
    Serial.println(" command received to send BLE-command 20 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[19],sizeof(PmUSSECMDs[19]));
    }
    if (currentLine.endsWith("GET /S9")) {
    Serial.println(" command received to send BLE-command 22 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[21],sizeof(PmUSSECMDs[21]));
    }
    if (currentLine.endsWith("GET /L1")) {
    Serial.println(" command received to send BLE-command 11 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[10],sizeof(PmUSSECMDs[10]));
    }
    if (currentLine.endsWith("GET /L2")) {
    Serial.println(" command received to send BLE-command 12 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[11],sizeof(PmUSSECMDs[11]));
    }
    if (currentLine.endsWith("GET /L3")) {
    Serial.println(" command received to send BLE-command 13 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[12],sizeof(PmUSSECMDs[12]));
    }
    if (currentLine.endsWith("GET /L4")) {
    Serial.println(" command received to send BLE-command 14 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[13],sizeof(PmUSSECMDs[13]));
    }
    if (currentLine.endsWith("GET /L5")) {
    Serial.println(" command received to send BLE-command 23 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[22],sizeof(PmUSSECMDs[22]));
    }
    if (currentLine.endsWith("GET /L6")) {
    Serial.println(" command received to send BLE-command 24 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[23],sizeof(PmUSSECMDs[23]));
    }
    if (currentLine.endsWith("GET /L7")) {
    Serial.println(" command received to send BLE-command 25 to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[24],sizeof(PmUSSECMDs[24]));
    }
    if (currentLine.endsWith("GET /v1")) {
    Serial.println(" command received to send BLE-command 15 = v1 = Vol 100% to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[14],sizeof(PmUSSECMDs[14]));
    }
    if (currentLine.endsWith("GET /v2")) {
    Serial.println(" command received to send BLE-command 16 = v2 = Vol 50% to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[15],sizeof(PmUSSECMDs[15]));
    }
    if (currentLine.endsWith("GET /v3")) {
    Serial.println(" command received to send BLE-command 17 = v3 = Vol 30% to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[16],sizeof(PmUSSECMDs[16]));
    }
    if (currentLine.endsWith("GET /v4")) {
    Serial.println(" command received to send BLE-command 18 = v4 = Vol 0% to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[17],sizeof(PmUSSECMDs[17]));
    }
    if (currentLine.endsWith("GET /x")) {
    Serial.println(" command received to send BLE-command 19 = x = AUS to Enterprise");
    BlinkLED();
    pRemoteCharacteristic->writeValue(PmUSSECMDs[18],sizeof(PmUSSECMDs[18]));
    }
    if (currentLine.endsWith("GET /SOff")) {
    Serial.println(" command received to turn OFF Status LED");
    digitalWrite(LED_White, LOW);
    }
    if (currentLine.endsWith("GET /SOn")) {
    Serial.println(" command received to turn ON Status LED");
    digitalWrite(LED_White, HIGH);
    }
    if (currentLine.endsWith("GET /AOff")) {
    Serial.println(" command received to turn OFF Red LED");
    digitalWrite(LED_Red, LOW);
    }
    if (currentLine.endsWith("GET /AOn")) {
    Serial.println(" command received to turn ON Red LED");
    digitalWrite(LED_Red, HIGH);
    }
    if (currentLine.endsWith("GET /B0")) {
    Serial.println(" command received to make blue LED blink only on BLE CMDs");
    LED_BlueStatic = 0;
    digitalWrite(LED_Blue, LOW); // turn the external LED on (HIGH is the voltage level)
    }
    if (currentLine.endsWith("GET /B1")) {
    Serial.println(" command received to keep blue LED ON");
    LED_BlueStatic = 1;
    digitalWrite(LED_Blue, HIGH); // turn the external LED on (HIGH is the voltage level)
    }
    if (currentLine.endsWith("GET /d")) {
    Serial.println(" command received to deep-sleep ESP32 (disconnect from Enterprise). Repower to reconnect");
    esp_deep_sleep_start();
    }
    }
    }
    client.stop();
    Serial.println("Client disconnected");
    }
    }
    P.S.: hier noch ein Befehl, den ich nicht im obigen Code eingebaut habe, aber leicht ergänzt werden könnte: aa03be00ff → Vol = 75%; Viele Befehle funktionieren auch mit "be" statt "c8". Keine Ahnung was da der Unterschied ist!

    PPS: der Befehl aa080ac8ff fehlte noch. Er entspricht "Warpanrieb einschalten".
    Zuletzt geändert von MarkusCosi; In den letzten 3 Wochen.
  • MarkusCosi
    LoxBus Spammer
    • 28.09.2023
    • 314

    #2
    kurzes Update: ich habe noch ein paar Befehle oben ergänzt. Das Setup funktioniert prinzipiell. Leider ist der Webserver-part der ganzen Geschichte am ESP32 sehr unzuverlässig.
    Über Hilfe würde ich mich sehr freuen: Link zum Post!
    Update: es funktioniert nun mit einem TimeOut im loop().
    Zuletzt geändert von MarkusCosi; 28.04.2025, 15:55.

    Kommentar

    • Noschvie
      MS Profi
      • 24.09.2018
      • 584

      #3
      Na echt beeindruckend!

      Kommentar

      • Labmaster
        Lox Guru
        • 20.01.2017
        • 2695

        #4
        Ich hab schon mehrfach den Webserver im ESP32 verwendet incl. dem ganzen Captive Portal mit der Wifi/AP/STA configuration.
        Hatted a bisher noch keine Probleme bezüglich erreichbarkeit oder das man Anfragen mehrfach senden muss.
        Ich verwende hierfür bisher die ESp32 Asyc Webserver Library von ESP32Async" und dort als Basis die Examples. ( siehe auch https://github.com/ESP32Async/ESPAsyncWebServer )

        Einfach in der Arduino IDE bei den Library nach "ESP32Async" filtern und die Library "ESP Async WebServer" installieren.
        Dann halt unter File->Examples->in Liste unter "Examples from Custom Libraries" -> "Captive Portal" und "Simple Server" anschauen, verwenden, modifizieren.



        Kommentar


        • MarkusCosi
          MarkusCosi kommentierte
          Kommentar bearbeiten
          Danke für den Tipp! Ich werde das wohl nochmal bei Gelegenheit probieren. Ich hatte tatsächlich, bevor ich den Trick mit der TimeOut gefunden hatte, schonmal mit der Library angefangen; aber dann kamen eine Reihe von Fehlermeldungen beim Kompilieren zu denen ich nichts gefunden hatte.. Aber die von dir erwähnten Beispiele hatte ich mir da noch nicht angeschaut, vllt. hatte ich irgendwo einfach einen blöden Fehler...
      • Grestorn
        LoxBus Spammer
        • 11.07.2022
        • 456

        #5
        Mach mal ein Video von der NCC-1701 und wie Du sie steuerst! Das würde mich echt interessieren... Da könnte ich glatt schwach werden.

        Kommentar

        • MarkusCosi
          LoxBus Spammer
          • 28.09.2023
          • 314

          #6
          Hallo!

          Anbei mal ein Foto der Installation. Aktuell läuft noch alles nach wie vor problemlos und zuverlässig mit dem angepassten Code wie in Post Nummer 1 oben.
          Ich nutze einen virtuellen Ausgang um aktuell einen Torpedo-Sound zu triggern bei Bewegung im Flur (kann ich aber abstellen mit einem Schalter). Für die Licht-Steuerung will ich erst die 3 Batterien im Modell durch einen 4,5V-Batterie-Netzadapter (mit Dummy-Batterien) ersetzen um die Enterprise dauerhaft mit Strom zu versorgen (ginge auch per USB-C-Kabel, wäre aber etwas unschöner IMHO)...

          Außerdem habe ich mir den Torpedo-Effekt (Licht + Sound) und ein paar weitere Effekte auf einen Shelly BLU RC 4 Button gelegt ...
          Schon eine schöne Spielerei . Ab und an gibt es die Enterprise für 199 € im Angebot...


          Klicke auf die Grafik für eine vergrößerte Ansicht

Name: IMG_6959.png
Ansichten: 644
Größe: 5,97 MB
ID: 460788 Klicke auf die Grafik für eine vergrößerte Ansicht

Name: IMG_6964.jpg
Ansichten: 567
Größe: 2,80 MB
ID: 460789Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Enterprise.png
Ansichten: 485
Größe: 74,1 KB
ID: 460790

          Kommentar

          • MarkusCosi
            LoxBus Spammer
            • 28.09.2023
            • 314

            #7
            kurzes Update:
            Bei Batterie-Stromversorgung sind die Batterien (bei mir waren es Akkus) nach ca. 1-2 Wochen leer. Dabei habe ich die Sound-Effekte nicht durchgängig benutzt, und auch die anderen Effekte nicht besonders oft. Es liegt vermutlich am stetigen BLE Betrieb. Mit einem 4,5V Dummy-Batterie-Netzadapter funktioniert es auch (Kabel kann vom Maschinenraum in die Untertassensektion unauffällig hochgeleitet werden). Hierbei habe ich einen maximalen Stromfluss von ca. 126mA gemessen. Das deckte sich mit den vom Shelly Plug angezeigten 0-1W bei Betrieb der Effekte.. Mit einem 0,14mm^2 zwei-adrigen Kabel werde ich als nächstes versuchen die Stromversorgung dauerhaft hinzubekommen...

            Kommentar

            • MarkusCosi
              LoxBus Spammer
              • 28.09.2023
              • 314

              #8
              Kleines Update:

              Die Enterprise hat nun Dauerstrom spendiert bekommen. So sind keine Batterien mehr zu wechseln und ich kann die Beleuchtung ohne Bedenken nutzen. Praktischerweise ist nun auch der ESP32-Controller (s.o.) auf der Brücke hinter dem Turbo-Lift fest installiert und über die Vin/GND-Pins durch ein Step-Up Buck-Modul versorgt, sodass keine weitere Stromversorgung / Steckdose für den ESP32 benötigt wird. Dafür habe ich extra LEDs noch an den ESP angeschlossen um die selbe Rückmeldung / Infos die ich sonst über die On-Chip LEDs hatte nun auch auf einen Blick von der Enterprise zu bekommen. Leider musste ich dafür ein paar kleine Löcher in die Turbo-Lift Abdeckung bohren (von außen nicht zu sehen). Die sonstigen Kabel konnte ich ohne Bohrungen durch die Enterprise führen..
              • Stromversorgung:
                • Netzteil: 4,5V Netzteil Batterieadapter Batterieersatz für 3 Stück AA Batterien; 3 Dummy Batterien; Kabel: 2-adrig AWG24 → 0,2mm^2;
                • Verlängerungskabel: Kabel(10m Zwillingslitze, Querschnitt 0,14mm², Kupferlitze weiß ummantelt)
                • Buck Step-Up-Module (MT3608): 4.5V → 5.1V → Vin Pin / GND → ESP32 On-Chip regulator to 3.3V Betriebsspannung.. LEDs...
                • Verkabelung über Dupont-Stecker / Wago-Klemmen
              • Extra Lichter (Brücke links & rechts):
                • Blue & White LED (Adafruit LED Sequin; 5mA; "1206 size" LEDs, matched with a 100 ohm resistor) → Pin 32 (blue → orange cable → blue LED = Blink LED / BLE cmd) & 33 (yellow → yellow cable → yellow LED = Status LED).
              • Aufhängung:
                • 304-Edelstahl Drahtseil 2mm Stahlseil Ummantelt (15m, 7x7-Flechtung, Zugfestigkeit 120 kg, mit Quetschklemmen, Kauschen, M5 Augenbolzen-Schraubhaken, PVC-beschichtet)
                • M6 304-Edelstahl Mini Schraubkarabiner (135 Kg Belastbarkeit, 6 cm x 2,9 cm, Dicke 6 mm, maximale Öffnungsbreite beträgt 1 cm)
                • Umlenkrolle, M20/20mm, Edelstahl, Tragkraft 75kg
              Anbei ein paar Bilder dazu...

              P.S.: ich hatte noch einen Bug im Code bei der Befehlserkennung. /M11 etc. hat zunächst den Befehl /M1 ausgelöst, sodass immer unschön auch bei den Licht-Effekten ein kurzer Sound kam.. Den Code oben habe ich angepasst. Nun auch mit den extra LEDs. Den Code-Anteil kann man natürlich löschen / modifizieren...
              Angehängte Dateien
              Zuletzt geändert von MarkusCosi; 21.05.2025, 10:20.

              Kommentar


              • Grestorn
                Grestorn kommentierte
                Kommentar bearbeiten
                Wow!
            • MarkusCosi
              LoxBus Spammer
              • 28.09.2023
              • 314

              #9
              Anbei die Loxone Programmierung:

              Ich nutze eine Zeitschaltuhr (Digitalausgang? → Nein) um bei unterschiedlichen Zeiten bei Bewegung unterschiedliche Befehle auszuführen (tagsüber Sounds, Nachts nur Lichter). Die Befehle kann ich auch manuell über Radio-Tasten ausführen. Zusätzlich benötige ich den AUS-Befehl der Enterprise als Taster um verschiedene Effekte (z.B. einige Licht-Effekte) zeitlich zu begrenzen, da die an sonsten sehr lange (120min?) an bleiben.. Die extra LEDs (Blau und Weiß) habe ich jeweils als Schalter eingebunden.
              Angehängte Dateien

              Kommentar

              • MarkusCosi
                LoxBus Spammer
                • 28.09.2023
                • 314

                #10
                zur Info: das gesamte Setup (Netzteil + ESP32 + Enterprise) verbraucht ca. 0,9W im Mittel bei gelegentlicher Bewegungs-Triggerung.

                ...ich habe noch die letzten fehlenden "Command-Mode"-Befehle der Enterprise in den Code von Post Nr. 1 oben eingefügt, bzw. diesen aktualisiert.
                Dabei habe ich auch einen Sound durch Ausprobieren gefunden, der nicht durch den Command-Mode aktiviert werden kann ..

                Außerdem nutze ich jetzt noch GPIO 27 um eine rote LED (mit 330 Ohm vorgeschalten) zusätzlich zu steuern. Diese habe ich in die Mitte der 3 weißen LEDs im unteren "Sensor-Dome" mit einem ca. 10cm langen doppeladrigen Kabel "reingeschummelt". Dafür musste ich die zentrale Brücken-Sektion nochmal rausklicken und die Unterseite abschrauben.. Außerdem nun die Möglichkeit den EPS32 bis zum nächsten Re-Powering in den "deep sleep" zu schicken. Das erlaubt es auch mal die App zu nutzen wenn man denn möchte und die BLE Verbindung zum ESP32 bei Bedarf zu trennen..

                Anbei ein paar Bilder vom roten Alarm + neue rote LED an der Unterseite...

                Klicke auf die Grafik für eine vergrößerte Ansicht

Name: IMG_8593 copy.jpg
Ansichten: 181
Größe: 2,41 MB
ID: 465456
                Angehängte Dateien

                Kommentar

                • BastyJuice
                  Smart Home'r
                  • 11.01.2024
                  • 37

                  #11
                  Moin MarkusCosi,

                  Mega Idee und geile Ausführungen. Könntest du den Teil der Loxone Config in Bezug auf die 1701 Teilen?

                  Mir ist noch nicht ganz klar wieso du den Spannungswandler brauchst die ENTE kann ja via USB-C gepowerd werden dh denn CH340 (https://www.amazon.de/dp/B0C1JCGDFN) also hätten man denn doch einfach an die Interne Versorgung anklemmen können oder steh ich auf dem Schlauch.

                  Ich besitze auch den BOP von PlayMobil und bin am Überlegen ob dort die Modifikation auch möglich ist so könnte man einen Raumkampf Simulieren und beide Steuern :-)

                  Kommentar

                  • MarkusCosi
                    LoxBus Spammer
                    • 28.09.2023
                    • 314

                    #12
                    ...den Spannungswandler brauchte ich, da ich die Enterprise nicht per dickem USB-C Anschlusskabel mit Strom versorgen wollte. Auch is der USB-C Port wie ich finde wenig geeignet um eine unauffällige Stromversorgung einzurichten. Daher hatte ich mich für ein Netzteil mit Dummy-Batterien entschieden, da ließ sich ein Kabel unauffällig direkt bei der Aufhängung einschleusen... Aber grundsätzlich sollte es auch so funktionieren wie Du es schreibst, also mit einem Langen USB-C Kabel, ggf. Splitter um gleich noch mit dem selben USB-C-Netzteil den ESP-32 im Raumschiff mit zu versorgen. Sollte gehen!

                    Mit dem Bird of Prey liebäugle ich auch schon eine Weile ... Ein BLE-Modul hat der jedoch leider nicht (dann hätte man die gemeinsam steuern können). Ich würde den wohl mit einem Shelly Uni anbinden, oder einem ESP32 + 4 Channel Relay Modul (sowas vllt.).

                    Welcher Teil der Loxone Programmierung interessiert dich bzw. ist unklar? Ich habe ja schon einen Screenshot in meinem Post vom 21.05.2025 geteilt?

                    Kommentar

                    • BastyJuice
                      Smart Home'r
                      • 11.01.2024
                      • 37

                      #13
                      Zitat von MarkusCosi
                      Welcher Teil der Loxone Programmierung interessiert dich bzw. ist unklar? Ich habe ja schon einen Screenshot in meinem Post vom 21.05.2025 geteilt?
                      Die Screenshots sind leider ein wenig unscharf :-) Und wenn du es schon fertig hast insbesondere die Befehle brauch man Sie ja nicht nochmal bauen :-)

                      Aber richtig geiles Projekt

                      Kommentar


                      • MarkusCosi
                        MarkusCosi kommentierte
                        Kommentar bearbeiten
                        ...hier noch ein paar Details: die Befehle sind einfache virtuelle Ausgangsbefehle: im virt. Ausgang als Adresse http://<<IP_ESP32>> eingeben, dann als Befehle jeweils die gewünschten http-Commands an den ESP32, z.B. Befehl bei EIN (GET Methode) mit /S1 oder /L3 etc... (vgl. den ESP32-Code im ersten Post). Diese Befehle hängen am Radio-Button. Der Größer>0-Baustein sorgt dafür, dass ein Tastendruck jeweils den Radiobutton zurückstellt (geht an Flankenerkennung und Verzögerung 1s), und der Oder-Baustein sorgt noch dafür, dass bei Effekten die Lange laufen würden diese nach z.B. 30s angehalten werden. Das passiert über den Taster Enterprise AUS (Befehl: /x). Den zusätzlich von mir eingebauten LEDs am ESP32 habe ich noch Schalter spendiert... Der Trick mit der analogen Schaltuhr (Werte jeweils gewünschten Zeiträumen zuordnen) funktioniert über einen Analogspeicher, so verbunden wie im Screenshot gezeigt. Damit erreicht man das Triggern unterschiedlicher Effekte über Bewegung zu verschiedenen Tageszeiten...

                        Ich denke die Herausforderung bei dem Projekt liegt weniger in der Programmierung, sondern eher in der Aufhängung und Stromversorgung ... Die BLE-Geschichte (reverse engineering der BLE-App-Befehle) ist ja mit dem Code von oben gelöst ... Viel Erfolg bei deiner Realisierung, bin gespannt was bei Dir dabei herauskommt!
                    • BastyJuice
                      Smart Home'r
                      • 11.01.2024
                      • 37

                      #14
                      Ja hier eine kleine Rückmeldung zum Bird of Prey :-) der hat leider kein Bluetooth und oder Appsteuerung :-(

                      Kommentar


                      • MarkusCosi
                        MarkusCosi kommentierte
                        Kommentar bearbeiten
                        …daher würd ich das über zB einen Shelly Plus Uni machen (siehe Post Nr. 12), d.h. einfach die gewünschten Knöpfe brücken … ich schaue aktuell noch, ob esähnlich kompakte multi-kanal Module gibt…
                    • Maart
                      Azubi
                      • In den letzten 3 Wochen
                      • 2

                      #15
                      Hi Marcus, I just came across this message. Very cool. It seems we have been working in parallel on the same problem at exactly the same time.
                      Check out my GitHub https://github.com/VisionaiR3D/NCC1701_Playmobil

                      However my project completely spiralled out of control and turned into an AI driven voice controlled mission simulator.
                      Check it out here: https://youtu.be/mYgpTsvfttw?feature=shared
                      More info here: https://visionair3d.com/projectgenesis/

                      Kommentar

                      Lädt...