Govee: BLE > local API - Segmentsteuerung / Szenen

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

    #1

    Govee: BLE > local API - Segmentsteuerung / Szenen

    Bekanntlich sind viele der LAN-fähigen Govee-Lampen über eine lokale API per UDP steuerbar, d.h. direkt aus Loxone heraus ohne weitere Hardware/Loxberry o.Ä.
    Die lokale API ist dabei auf wenige Befehle beschränkt: An/Aus, Farbe, Farbtemperatur und Helligkeit. Dabei geht man wie folgt vor:
    • virt. Ausgang (siehe hier) anlegen mit Adresse: /dev/udp/<<IP>>/4003
    • virt. Ausgangs-Befehl anlegen (Methode: GET), z.B.
      • On/Off: bei EIN: {"msg":{"cmd":"turn","data":{"value":1}}}; bei AUS: {"msg":{"cmd":"turn","data":{"value":0}}}
      • Color: bei EIN: {"msg":{"cmd":"colorwc","data":{"color": <v>,"colorTemInKelvin":0}}}; v={"r":R,"g":G,"b":B}
      • Brightness: "msg":{"cmd":"brightness","data":{"value":100} }}
    testen kann man das auch per Terminal / Kommando-Zeile, z.B. via echo -n '{"msg":{"cmd":"turn","data":{"value":1}}}' | nc -u -w1 <<IP>> 4003

    -------------------
    ALLGEMEINES (Teil 1) - ptReal / XOR-Prüfsumme / Base64-Kodierung
    -------------------

    Ein weiterer nicht dokumentierter Befehl ermöglicht es sämtliche Einstellungen die man per Govee-APP, also letztendlich per Bluetooth (BLE), auf dem Handy vornimmt auch per lokaler LAN API per UDP zu setzen:
    • {"msg":{"cmd":"ptReal","data":{"command":[CMD]}}}
    Einzubinden in Loxone über einen virt. Ausgangsbefehl analog zu der vorherigen Vorgehensweise. Z.B. kann man für CMD <v> setzen und dem Befehl geeignete CMDs füttern die aus einem Status-Baustein kommen.

    Der CMD-String ist dabei ein Base64-kodierter stets 20 Byte (jeweils in Hex) langer Befehl, oder aber eine Reihe von Base64-kodierten Befehlen (durch Kommas getrennt=Multi-Packet-Befehl, s.u.) die ursprünglich jeweils 20 Byte lang sind.
    Folgende zwei einfache Befehle sollen als Beispiel dienen, wobei hier das zweite & dritte Bytes die eigentlichen Daten (erste Byte: 01: On/Off Daten; zweites Byte: 01=On/00=Off) enthält und das erste Byte (33) die Art des Pakets kodiert (beides fett). Das letzte Byte (fett, unterstrichen) ist eine Hex-XOR-Prüfsumme. Die vielen 00-Bytes müssen (siehe Beispiele später) ggf. ergänzt werden (=zero-padding, grau) bis es insgesamt 19 Bytes sind, sodass durch die Prüfsumme 20 bytes einen Befehl ergeben (vor der Base64-Konvertierung).
    • On: 33 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 33 → CMD="MwEBAAAAAAAAAAAAAAAAAAAAADM="
    • Off: 33 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 → CMD="MwEAAAAAAAAAAAAAAAAAAAAAADI="
    Diese Prüfsumme muss man bei eigenen Befehlen die man sich zusammenbaut stets berechnen bevor man die Hex>Base64-Kodierung vornimmt, z.B. mit einem Online-Tool wie hier.
    Die Kodierung Hex>Base64 im letzten Schritt (jeweils der String nach dem Pfeil "→") kann man auch online durchführen, z.B. mit einem Tool wie hier.

    Man kann nun entweder bekannte BLE Befehle benutzen (Liste), oder aber bestimmte Systematiken die durch Reverse-Engineering bereits bekannt wurden verwenden (oder selbst durch systematisches Vorgehen herausfinden). So ist bspw. bekannt, wie man einige Szenen mit ID < 255 per einfachem Befehl setzen kann, siehe Befehls-Berechnung hier bzw. Erläuterungen hier.
    Weitere Befehle findet man hier.

    Einiges scheint gut zu funktionieren und universell:
    • Scenes: 33 05 04 ID 00 .. 00 ChecksumXOR (ID = hex Wert von dec-ID wie hier oder per curl "https://app2.govee.com/appsku/v1/lig...ries?sku=H6076" -H 'AppVersion: 6.3.11' -s | jq '[.data.categories[].scenes[] | {name: .sceneName, code: .lightEffects[0].sceneCode}]')
    • On/Off: 33 01 ONOFF 00 .. 00 ChecksumXOR (ONOFF: 01=On; 00=Off)
    • Brightness: 33 04 Br 00 .. 00 ChecksumXOR (Br: 0 .. 64 = 0...100%)
    ------------------------
    Music Modes für H6076
    ------------------------

    Jedoch musste ich feststellen, dass Vieles was bereits bekannt ist bei meiner Govee-Lampe (H6076) nicht funktioniert bzw. scheinbar nicht universell funktioniert. D.h., z.B. für das setzen des Music-Modes scheint es diverse Befehle zu geben je nach Gerät (siehe hier, hier, hier bzw hier)
    • 33 05 0c ... / 33 05 01 ... / 33 05 13 ...
    Letztendlich war es bei mir aber 33 05 0f ...:
    • 33 05 0f ID Sens 00 ... 00 ChecksumXOR
    ID: 00: Energie; 04: Rythmus; 08: Bouncen; 02: Hüpfen; 06: Schlag; 07: sprühen
    Sens: 0..64 (Sensibilität: min ... max)

    Andere Music-Modi erfordern wiederum, ähnlich wie schon bei vielen Szenen, Multi-Packet Befehle (s.u.).

    Herausgefunden habe ich das wie folgt, und es erlaubt im Prinzip beliebige Befehle die man sonst nur mit der App geben kann:

    -----------------------------------------------------
    ALLGEMEINES (Teil 2): BLE Logging und Befehls-Extraktion
    -----------------------------------------------------

    Man benötigt dazu ein BLE-Log des Smartphones. Für ein iPhone geht es wie folgt:
    1. BLE-Aufzeichung vorbereiten: Mit einem Apple Developer Account (kostenfrei) geht man per Handy-Browser auf folgende Seite und klickt neben "Bluetooth for iOS/iPadOS" auf "Profile".https://developer.apple.com/bug-repo...ooth%20logging. Dieses installiert man im folgenden. Danach ist das Logging aktiv!
    2. BLE Befehle aufzeichnen: in der Govee-App dann die gewünschten Einstellungen vornehmen / Befehle absetzen. Am besten die Sequenz der Befehle aufschreiben und ggf. zwischendurch mit einfachen Befehlen ergänzen, z.B. On / Off
    3. Auslesen / Datei erstellen: gleichzeitig 1-2sek drücken: beide Vol-Tasten links & Taste rechts → vibriert kurz
    4. Übertragen: ca. 10min warten, dann: Einstellungen → Allgemein → Datenschutz & Sicherheit → Analyse & Verbesserungen → Analysedaten → sysdiagnose_YYYY.MM.DD_HH-MM-SS+0100_iPhone-OS_iPhone_TYPE → share → Airdrop to MacOS
    5. Analysieren: Download & install Wireshark für zB MacOS: https://www.wireshark.org/#downloadLink
    6. Wireshark starten:
      1. Open a capture file: .../Downloads/sysdiagnose_YYYY.MM.DD_HH-MM-SS+0100_iPhone-OS_iPhone_TYPE/logs/Bluetooth/bluetoothd-hci-latest.pklg
      2. in der Eingabezeile einen der folgenden Display-Filter oben setzen: (weitere Infos hier und hier)
        • alle CMDs außer alive: frame.len == 0x20 && bluetooth.src == 00:00:00:00:00:00 && btatt.opcode == 0x52 && btatt.value[0:1] != aa
        • Single-Packet-CMDs: frame.len == 0x20 && bluetooth.src == 00:00:00:00:00:00 && btatt.value contains 0x33 && btatt.opcode == 0x52 && btatt.value[0:1] != aa
        • Multi-Packet-CMDs: frame.len == 0x20 && bluetooth.src == 00:00:00:00:00:00 && btatt.value contains 0xa3 && btatt.opcode == 0x52 && btatt.value[0:1] != aa
      3. BLE-Befehle erkennen/extrahieren: unten rechts bzw. im Feld btatt.value
    7. ggf. Profil auf dem iPhone wieder deinstallieren: Einstellungen → Allgemein → VPN und Geräteverwaltung → Profil auswählen und deinstallieren. (deinstalliert sich sonst nach 4 Tagen von selbst)
    Mit der (Display-)Filterung in Wireshark sollten von vielen tausenden Befehlen nur die relevanten übrig bleiben. Die Befehle erkennt bzw. extrahiert man nun wie folgt:
    • aa .. .. → keep alive packets: btatt.value → uninteressant und daher oben rausgefiltert
    • 33 .. .. → einfache Befehle mit nur einem Satz von 20 bytes. Z.B. Szenen mit ID<255 aktivieren bzw. Szene in App aktiv setzen, On/Off, Brightness, etc...
    • a3 .. .. → Multi-Packet Befehle... Syntax wie hier. Z.B. Segmente steuern, Szenen mit ID>255, einige Music-Modes, ...

    -----------------------------------------------------
    ALLGEMEINES (Teil 3): Multi-Packet-Befehle
    -----------------------------------------------------

    Einige Befehle sind länger als 20 Byte. Die Govee-App scheint die Daten dann auf mehrere 20 Byte lange a3-Befehle aufzuteilen, d.h. in eine Sequenz von Multi-Packet-Befehlen. Diese sehen wie folgt aus:
    • a3 00 01 #ofPackets Daten XORChecksum
    • a3 01 Daten (weitergeführt) XORChecksum
    • ...
    • a3 ff Daten (letzter Datensatz) XORChecksum
    Die einzelnen Befehle für die ptReal-Schnittstelle sind jeweils mit Prüfsumme und Base64-kodiert zu bilden und können dann mit Kommas getrennt in einem einzigen LAN API Aufruf abgesetzt werden (siehe Teil 1 oben). Als Beispiel für einen Multi-Packet-Befehl soll folgendes dienen:

    Multi packet write (hier), Aurora:
    • a3 00 01 05 02 02 20 00 00 00 01 02 01 ff 32 01 00 00 00 49 → owABBQICIAAAAAECAf8yAQAAAEk=
    • a3 01 00 fa 32 03 00 ff 00 00 ff ff aa ff 00 03 00 80 00 40 → owEA+jIDAP8AAP//qv8AAwCAAEA=
    • a3 02 00 00 00 23 00 00 00 03 02 01 ff 19 03 fa 00 00 02 9f → owIAAAAjAAAAAwIB/xkD+gAAAp8=
    • a3 03 fa 00 04 7f ff 00 ff ff 00 a0 ff ff 00 ff ff 14 01 6b → owP6AAR//wD//wCg//8A//8UAWs=
    • a3 ff ef 00 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 4c → o//vAAD/AAAAAAAAAAAAAAAAAEw=
    dabei sind im ersten und den weiteren Befehlen des Multi-Packet-Befehls als header (oben fett) die folgenden Infos enthalten:
    Packet#: # of packet: 00, 01, 02, .., ff=End
    Begin: 01 = value indicating Multi-Packet start (nur im ersten Packet)
    #ofPackets: total # of packets in this Multi-Packet write CMD, z.B. oben: 05=5 nacheinander folgende BLE-Befehle bzw. Packets eines einzigen Multi-Packet-Befehls...

    Ergänzt wird dieser Multi-Packet-Befehl in diesem Beispiel von einem einfachen Single-Packet-Befehl der in der Log folgte:
    • 33 05 04 d0 2b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c9 → MwUE0CsAAAAAAAAAAAAAAAAAAMk=
    In Summe kann man den Befehl für de Szene "Aurora" bei der H6076-Lampe also wie folgt über die lokale LAN API replizieren:
    • CMD="owABBQICIAAAAAECAf8yAQAAAEk=","owEA+jIDAP8AAP//qv8AAwCAAEA=","owIAAAAjAAAAAwIB/xkD+gAAAp8=","owP6AAR//wD//wCg//8A//8UAWs=","o//vAAD/AAAAAAAAAAAAAAAAAEw=","MwUE0CsAAAAAAAAAAAAAAAAAAMk ="
    Mit obiger Methode kommt man also an die Multi-Packet-Befehle z.B. der Szenen heran. Viele davon sind wie gesagt auch für viele (aber längst nicht alle!) Lampen bereits protokolliert, siehe diese Liste.

    -----------------------------------------------------
    Segment-Steuerung (H6076): Teil 1: Allgemeine Syntax
    -----------------------------------------------------

    Folgendes ist neu: man kann auch Segmente bzw. Pixel gezielt einzeln steuern. Im Internet fand ich folgende Syntax, die aber für meine Lampe nicht funktionierte, siehe hier. Stattdessen funktioniert bei meiner Govee H6076-Stehlampe das ganze wie folgt:

    Es sind je 6 LEDs in einem kontrollierbarem Pixel im Grafitti Modus der App zusammengefasst und einzeln einstellbar. Dazu gibt es eine definierte Hintergrund-Farbe (& Helligkeit).

    Durch systematisches Testen habe ich folgende allgemeine Syntax des Graffiti Modus erkannt:
    • a3 Packet# Begin #ofPackets Grafitti BewModus Geschw HInt HColR HColG HColB total#Segments #Pixels1 Col1R Col1G Col1B Seg1ID1 Seg1ID2 ... #Pixels2 Col2R Col2G Col2B Seg2ID1 Seg2ID2 ... ... 00 .. 00 ChecksumXOR
    • a3 P# ... (so viele Pakete wie notwendig für den Befehls-String) ChecksumXOR
    folgende Bytes sind dabei im Multi-Packet-Befehl:
    • Packet#: # of packet: 00, 01, 02, .. ff=End
    • Begin: 01 = value indicating multipacket start
    • #ofPackets: total # of packets in this multi-packet write cmd
    • Grafitti: value indicating Grafitti mode?
    • BewModus: 0a: Runter; 09: Hoch; 02: Zyklus; 13: Verblassen; 0f: Funkeln; 14: Atmen
    • Gewsch: 00 .. 64 (min=fix to max), hex values
    • HInt: Intensity of Background color: 00 .. 64 (min .. max)
    • HColR / HColG / HColB: RGB-Color values für den Hintergrund x: 00 .. ff (=0..255)
    • total#Segments: Anzahl der nachfolgend definierten Segmente
    • #Pixelsx: # of Pixels in Segment x
    • ColxR / ColxG / ColxB: RGB-Color values for Segment x: 00 .. ff (=0..255)
    • SegxIDy: ID des Pixels y des Segments x.
    • ChecksumXOR: XOR byte checksum
    Je nach Anzahl definierter Segmente (=Pixel-Gruppen gleicher Farbe) kann ein solcher Befehl über mindestens 2, aber auch mehr Packets aufgeteilt sein. Dabei sind die headers jeweils fix und enthalten keine Daten (also die ersten 4 bytes des ersten, und die ersten 2 bytes der folgenden Packets). Die obige Grafitti-Befehls-Syntax (entsprechend den eigentlichen "Nutz-Daten" des Befehls) wird also einfach auf die Packets aufgeteilt und "schiebt sich sozusagen durch" (an den headern jeweils vorbei / um die header rum). Jeder Teil-Befehl enthält eine XOR-Checksum und header wie oben beschrieben.

    Die 14 Pixel (1 .. 14) sind dabei wie folgt durchnummeriert bzw. haben folgende IDs:
    • 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
    Die Segmente werden also nacheinander jeweils durch die Anzahl der enthaltenen Pixel, die Farbe als RGB-Triplet, und die IDs der dazugehörigen Pixel definiert.

    Folgender einfacher Befehl muss dabei zunächst zumindest am Anfang mitgesendet werden (=Grafitti-Modus?):
    • 33 05 0a 20 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1f → CMD="MwUKIAMAAAAAAAAAAAAAAAAAAB8="
    -----------------------------------------------------
    Segment-Steuerung (H6076): Teil 2: Beispiel 1
    -----------------------------------------------------

    Folgendes Beispiel, wobei ich die Farb-Byte-Triplets bold gesetzt habe um die Struktur der nacheinander folgenden Segmente (#Segments1 Col1R Col1G Col1B LEDxID1 LEDxID2 ...) zu verdeutlichen:

    Pixel #1: rot, #5: grün, #10: blau, #11&#12: gelb, Rest=Hintergrund: AUS
    • a3 00 01 02 03 09 00 01 00 00 00 04 01 ff 00 00 00 01 00 50 → owABAgMJAAEAAAAEAf8AAAABAFA=
    • a3 ff ff 00 04 01 00 00 ff 09 02 64 64 00 0a 0b 00 00 00 53 → o///AAQBAAD/CQJkZAAKCwAAAFM=
    d.h. es ergibt sich folgender Befehl für die LAN-API: CMD="owABAgMJAAEAAAAEAf8AAAABAFA=","o///AAQBAAD/CQJkZAAKCwAAAFM=","MwUKIAMAAAAAAAAAAAAAAAAAAB8="

    Testen kann man z.B. im Terminal via
    echo -n '{"msg":{"cmd":"ptReal","data":{"command":["owABAgMJAAEAAAAEAf8AAAABAFA=","o///AAQBAAD/CQJkZAAKCwAAAFM=","MwUKIAMAAAAAAAAAAAAAAAAAAB8="]}}}' | nc -u -w1 <<IP>> 4003

    So kann man also einzelne steuerbare Pixel = 6er-LED-Gruppen in beliebigen Farben und Kombinationen schalten, z.B. um Stati anzuzeigen (siehe das Projekt hier, oder hier).

    ---------------------------------------------------------
    Segment-Steuerung (H6076)​: Teil 3: Beispiel 2: Prozent-Balken
    -----------------------------------------------------​----

    Folgende Sequenz gibt eine wachsende Anzahl der Pixel farbig aus (gelb: 64 64 0), d.h. ein einziges Segment (total#Segments=01=1) wachsender Länge (wachsende Anzahl an Pixel, bzw. mehr und mehr PixelIDs), z.B. nutzbar als Prozent-Balken (wie hier. Z.B. für eine Anzeige der PV-Produktion oder des Programmfortschritts der Kaffeemaschine):
    [Man kann die Farbe leicht ändern, aber muss dafür die Prüfsumme neu berechnen und die Hex2Base64-Kodierung erneut vornehmen]
    Die unterstrichenen Bytes im Folgenden sollen die Systematik verdeutlichen und zeigen die LED1IDs von 00=erstes 6er-LED-Pixel bis 0d=14. Pixel = letztes Pixel des einen Segments.

    Alle Pixel AUS
    a3 00 01 02 03 09 00 00 00 00 00 00 00 00 00 00 00 00 00 aa → owABAgMJAAAAAAAAAAAAAAAAAKo=
    a3 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5c → o/8AAAAAAAAAAAAAAAAAAAAAAFw=
    CMD="owABAgMJAAAAAAAAAAAAAAAAAKo=","o/8AAAAAAAAAAAAAAAAAAAAAAFw=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 01 64 64 00 00 00 00 aa → owABAgMJAAAAAAABAWRkAAAAAKo=
    a3 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5c → o/8AAAAAAAAAAAAAAAAAAAAAAFw=
    CMD="owABAgMJAAAAAAABAWRkAAAAAKo=","o/8AAAAAAAAAAAAAAAAAAAAAAFw=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-2. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 02 64 64 00 00 01 00 a8 → owABAgMJAAAAAAABAmRkAAABAKg=
    CMD="owABAgMJAAAAAAABAmRkAAABAKg=","o/8AAAAAAAAAAAAAAAAAAAAAAFw=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-3. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 03 64 64 00 00 01 02 ab → owABAgMJAAAAAAABA2RkAAABAqs=
    CMD="owABAgMJAAAAAAABA2RkAAABAqs=","o/8AAAAAAAAAAAAAAAAAAAAAAFw=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-4. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 04 64 64 00 00 01 02 ac → owABAgMJAAAAAAABBGRkAAABAqw=
    a3 ff 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5f → o/8DAAAAAAAAAAAAAAAAAAAAAF8=
    CMD="owABAgMJAAAAAAABBGRkAAABAqw=","o/8DAAAAAAAAAAAAAAAAAAAAAF8=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-5. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 05 64 64 00 00 01 02 ad → owABAgMJAAAAAAABBWRkAAABAq0=
    a3 ff 03 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5b → o/8DBAAAAAAAAAAAAAAAAAAAAFs=
    CMD="owABAgMJAAAAAAABBWRkAAABAq0=","o/8DBAAAAAAAAAAAAAAAAAAAAFs=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-6. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 06 64 64 00 00 01 02 ae → owABAgMJAAAAAAABBmRkAAABAq4=
    a3 ff 03 04 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5e → o/8DBAUAAAAAAAAAAAAAAAAAAF4=
    CMD=owABAgMJAAAAAAABBmRkAAABAq4=","o/8DBAUAAAAAAAAAAAAAAAAAAF4=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-7. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 07 64 64 00 00 01 02 af → owABAgMJAAAAAAABB2RkAAABAq8=
    a3 ff 03 04 05 06 00 00 00 00 00 00 00 00 00 00 00 00 00 58 → o/8DBAUGAAAAAAAAAAAAAAAAAFg=
    CMD="owABAgMJAAAAAAABB2RkAAABAq8=","o/8DBAUGAAAAAAAAAAAAAAAAAFg=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-8. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 08 64 64 00 00 01 02 a0 → owABAgMJAAAAAAABCGRkAAABAqA=
    a3 ff 03 04 05 06 07 00 00 00 00 00 00 00 00 00 00 00 00 5f → o/8DBAUGBwAAAAAAAAAAAAAAAF8=
    CMD="owABAgMJAAAAAAABCGRkAAABAqA=","o/8DBAUGBwAAAAAAAAAAAAAAAF8=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-9. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 09 64 64 00 00 01 02 a1 → owABAgMJAAAAAAABCWRkAAABAqE=
    a3 ff 03 04 05 06 07 08 00 00 00 00 00 00 00 00 00 00 00 57 → o/8DBAUGBwgAAAAAAAAAAAAAAFc=
    CMD="owABAgMJAAAAAAABCWRkAAABAqE=","o/8DBAUGBwgAAAAAAAAAAAAAAFc=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-10. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 0a 64 64 00 00 01 02 a2 → owABAgMJAAAAAAABCmRkAAABAqI=
    a3 ff 03 04 05 06 07 08 09 00 00 00 00 00 00 00 00 00 00 5e → o/8DBAUGBwgJAAAAAAAAAAAAAF4=
    CMD="owABAgMJAAAAAAABCmRkAAABAqI=","o/8DBAUGBwgJAAAAAAAAAAAAAF4=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-11. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 0b 64 64 00 00 01 02 a3 → owABAgMJAAAAAAABC2RkAAABAqM=
    a3 ff 03 04 05 06 07 08 09 0a 00 00 00 00 00 00 00 00 00 54 → o/8DBAUGBwgJCgAAAAAAAAAAAFQ=
    CMD="owABAgMJAAAAAAABC2RkAAABAqM=","o/8DBAUGBwgJCgAAAAAAAAAAAFQ=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-12. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 0c 64 64 00 00 01 02 a4 → owABAgMJAAAAAAABDGRkAAABAqQ=
    a3 ff 03 04 05 06 07 08 09 0a 0b 00 00 00 00 00 00 00 00 5f → o/8DBAUGBwgJCgsAAAAAAAAAAF8=
    CMD="owABAgMJAAAAAAABDGRkAAABAqQ=","o/8DBAUGBwgJCgsAAAAAAAAAAF8=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-13. Pixel gelb, Rest AUS
    a3 00 01 02 03 09 00 00 00 00 00 01 0d 64 64 00 00 01 02 a5 → owABAgMJAAAAAAABDWRkAAABAqU=
    a3 ff 03 04 05 06 07 08 09 0a 0b 0c 00 00 00 00 00 00 00 53 → o/8DBAUGBwgJCgsMAAAAAAAAAFM=
    CMD="owABAgMJAAAAAAABDWRkAAABAqU=","o/8DBAUGBwgJCgsMAAAAAAAAAFM=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="

    1.-14. Pixel (=alle) gelb
    a3 00 01 02 03 09 00 00 00 00 00 01 0e 64 64 00 00 01 02 a6 → owABAgMJAAAAAAABDmRkAAABAqY=
    a3 ff 03 04 05 06 07 08 09 0a 0b 0c 0d 00 00 00 00 00 00 5e → o/8DBAUGBwgJCgsMDQAAAAAAAF4=
    CMD="owABAgMJAAAAAAABDmRkAAABAqY=","o/8DBAUGBwgJCgsMDQAAAAAAAF4=","MwUKIAMAAAAAAAAAAAAAA AAAAB8="
    Zuletzt geändert von MarkusCosi; 27.11.2024, 09:42.
  • MarkusCosi
    LoxBus Spammer
    • 28.09.2023
    • 369

    #2
    Anbei noch ein paar Screenshots zur Methode (Wireshark & Loxone Config für einen Prozent-Balken mit der H6076-Govee-Stehlampe)...
    Der Status-Baustein nutzt noch einen zweiten Eingang um zwischen zwei unterschiedlichen Farben zu schalten...

    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: Govee1.jpg Ansichten: 0 Größe: 778,4 KB ID: 446779
    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: goveeStatus.jpg Ansichten: 0 Größe: 805,5 KB ID: 446778
    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: LyraConfig.jpg Ansichten: 0 Größe: 121,5 KB ID: 446777
    Zuletzt geändert von MarkusCosi; 15.11.2024, 09:07.

    Kommentar

    • MarkusCosi
      LoxBus Spammer
      • 28.09.2023
      • 369

      #3
      ... bei der Govee Weihnachtsbaum-Lichterkette H70C4 (20m) sind in der App 10 Segmente mit je 20 LEDs einzeln steuerbar.

      ------------------------------------------------------------------------
      H70C4 - Allgemeine Syntax für Grafitti Modus (nicht per LAN-API absetzbar?)
      ------------------------------------------------------------------------

      Interessanterweise gibt es nun doch BLE-Packets mit mehr als 20 Bytes die mit a4 ... anfangen.

      Die Syntax für den Graffitti.Modus ist dabei wie folgt:
      • a4 00 00 01 02 00 03 BewMode Geschw IntHint ColHintR ColHintGColHintB#totalSegments 00 #PixelsSegment1 00 Col1R Col1G Col1B 00 00 LED1xIDs #PixelsSegment2 00 Col2R Col2G Col2B 00 00 LED2xIDs ... XORChecksum
      • a4 ff ff a4
      • 33 05 0a 20 03 03 00 00 00 00 00 00 00 00 00 00 00 00 00 1c
      Die IDs der LEDs=Pixel stellen sich dabei offensichtlich wie folgt dar, d.h. wird von 0 ... 200 durchgehend in hex codiert (von 0x00 bis 0xc7):
      LEDs: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (1. Segment)
      IDs: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13
      LEDs: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (2. Segment)
      IDs: 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27
      LEDs: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (3. Segment)
      IDs: 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b
      usw...

      -------------------------------------------------------------
      H70C4 - Beispiele für a4-Befehle (nicht per LAN-API absetzbar?)
      -------------------------------------------------------------

      Eine Befehlsfolge wie folgt schaltet im Segment #1 die LEDs bzw. Pixel 1, 6, und 19 rot (den 2.-3. Befehl zus. wie oben):
      • a4 00 00 01 02 00 03 13 33 64 01 01 01 01 00 03 00 ff 00 00 00 00 02 05 12 09
      Weiteres Beispiel: Segment 1, LED 1, 6, 19, 20, Segment 3, LED 3, 10, 20 (vgl.: 0x3b → 59 → LED 60 = LED 20 im 3. Segment)
      • a4 00 00 01 02 00 03 13 33 64 01 01 01 01 00 07 00 ff 00 00 00 00 02 05 12 13 2a 31 3b 3e
      zus. Segment 10, LED 3, 4, 20 (vgl. 0xb6 → 182 → LED 183 = LED 3 im 10. Segment, 0xc7 → 199 → LED 200 = LED 20 im 10. Segment)
      • a4 00 00 01 02 00 03 13 33 64 01 01 01 01 00 0a 00 ff 00 00 00 00 02 05 12 13 2a 31 3b b6 b7 c7 f5
      Leider funktioniert diesmal die Base64-kodierte Version solcher Befehls-Triplets (also die je zwei a4-Befehle plus dem 33 05 0a .. -Befehl) nicht über die lokale API per UDP und dem ptReal-Argument. Hat jemand vllt. eine Idee warum?

      -------------------------------------------------------------
      H70C4 - Beispiele für Szenen & Music-Mode
      -------------------------------------------------------------

      Die sonstigen 33er und a3-Befehle funktionieren wie immer, e.g. Szenen wie folgt:
      • Sonnenuntergang: CMD="MwUEAQAAAAAAAAAAAAAAAAAAADM="
      • Aurora: CMD="owABBQICIAAAAAECAZw+AQAAACY=","owED8jIDCP+qCP 8VAA D/AwCAAKE=","owIAAAApAAAAAwIBrhkB+gAAA8c=","owPtAAZk/ggAAACLAP8AAAAI/1o=","o/8VAAAAEAD8AAD/AAAAAAAAAFo=","MwUEIjAAAAAAAAAAAAAAAAAAACA="
      • Weihnachten: CMD="owABBgICKQAAAA8AAf//AAAUFIM=","owEC/AUGAAAA/wAAAAAAAAAAAKA=","owL/AAAAAAAA/BAA5QApAAAAD3E=","owMAAf//AAAUFAL8BQb/AAAAAKM=","owQAAAAAAP8AAAAAAAAAAgD8ErQ=","o/8A5QAAAAAAAAAAAAAAAAAAALk=","MwUELTAAAAAAAAAAAAAAA AAAAC8="
      • Kerzenlicht: CMD="MwUECQAAAAAAAAAAAAAAAAAAADs="
      • Schneien: CMD="owABCQIFHQAAAAIAAf//AIAUFDI=","owED5RQCB1H/B+v/AACAAACAAOg=","owIaAAIyGQIB/wADzgYQAIAUASA=","owP///8AAIAAAIAAGgACPAMCAXs=","owT/AAPMAgIAjhQB////AACAAHM=","owUAgAAaAAIyAgIB/wAD0QwLACc=","owaAFAH///8AAIAAAIAAGgACPOs=","owcFAgH/AAPTCgYAgBQB////AOs=","o/8AgAAAgAAAAAAAAAAAAAAAAFw=","MwUEMjIAAAAAAAAAAAAAA AAAADI="
      • Sonnenaufgang: CMD="MwUEAAAAAAAAAAAAAAAAAAAAADI="
      • Sternenhimmel: CMD="owABDAIFKQAAAAECAU0zAn8BAYE=","owGDNAEGAAD/iwD/AAD/AP//AGY=","owIA/4sA/wAA1wAAHQAgAAJ4GaM=","owMAAf8AA8wDAwM0AQMA//8AAKQ=","owT//wAABAD/AACAACk1AAABAME=","owUDsgACyQH/gAAAyQcBAAAAAG0=","owYBMgMAAQIAAAD///8WAP8SAJI=","owf8ACkyAAABAAOyAALKAf+YAF0=","owgAyw cBAAAAAAGPAwABAgAAAOg=","own///8UAP8QAPsAJiQAAAEAA1U=","owr/AALKAf//AADKBwEAAAAAAVI=","o/8jAwABAf/McQQA9gAA/gAAADI=","MwUEJDAAAAAAAAAAAAAAAAAAACY="
      • Feuer: CMD="owABCQIFGkMAAAECAcxlA4AUFN0=","owEC4woB/zkHFwD8EwD8ABokALM=","owIAAQIBzGYBgBQUAoAUAf9HB6A= ","owMXAP8AAIAAHQAAAAECAaoEA3o=","owTaCgoA5RQC/wAA/0AHAACAAEk=","owUAgAAaJAAAAQIBy2YDgBQUAjY=","owaAF AH/FwcVAP8AAIAAHQACjCY=","owcZAAFcNgPoAwMA9BQC/xwH/8Q=","o/9ABwAAgAAAgAAAAAAAAAAAABs=","MwUEKjAAAAAAAAAAAAAAA AAAACg="
      • Abendrot: CMD="owABBwIDJgAAAAQCAYdcAwAUFF0=","owEDABQF/yoH/4RU/3QP/4lh/yE=","owIgBwAAgAAAgAAdMgAAAgIB918=","owNMA3cyMgPcMgL/XiXrKf8XANk=","owT8AAAAAB01AAACAgH4TQOEMnI=","owUyA9wyAv9eJeYX/hUA/AAAABk=","o/8AAAAAAAAAAAAAAAAAAAAAAFw=","MwUEKzAAAAAAAAAAAAAAAAAAACk="
      • Milchstraße: CMD="owABCAIEJmAAAAUCAZIAAgAUFHw=","owED5RQFB0n/CP8P/38A/wAAi+g=","owIA/xAA/AAAgAAaAAAAAQIB/9U=","owNeAQAUFAAAFAEAABkAAIAAAHM=","owSAACZkAAAF A gGSAAIAFBQD5RU=","owUUBQdJ/wj/D/9/AP8AAIsA//U=","owYEAPcQAPwAGgACBQMAAUwAA+o=","o//GFBQAABQBlpaWAACAAACAABk=","MwUEazAAAAAAAAAAAAAAAA AAAGk="
      • Himmel: CMD="owABBwIDKQAAAAQAAczMAIAUFAg=","owEDTxQGAP//Bk7+////Bj7+AHM=","owL//wD/yAAAgAAAgAAdMQEADLc=","owMCAZUAA8kUFAItFAL//////zo=","owT/FQD5EADqAB2BAgMCAgH/AC0=","owUDzBRkAi0UAv///////wEA9NU=","o/8AAIAAAAAAAAAAAAAAAAAAANw=","MwUEbzAAAAAAAAAAAAAAA AAAAG0="
      • Music-Mode: Energy, sens max; CMD="MwUTBWMB/wAAAAAAAAAAAAAAAL0="

      -------------------------------------------------------------
      H70C4​ - Beispiele für Segment-Steuerung
      -------------------------------------------------------------​​

      Edit:
      Die folgende Syntax, extrahiert aus dem Color-Modus der Govee-App in dem die Steuerung der Segmente erfolgt, funktioniert für die H70C4​ um die 10 Segmente à 20LEDs (also Gruppen von LEDs, nicht einzelne LEDs) zu steuern, wobei wie üblich die Konvertierung hex2base64 erforderlich ist um den Befehl per ptReal-Schnittstelle an die lokale LAN-API zu schicken:

      Die Nummerierung erfolgt wie 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 in hex:
      Segm: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
      ID1/2s: 01 00, 02 00, 04 00, 08 00, 10 00, 20 00, 40 00, 80 00, 00 01, 00 02

      Farbe Ändern: (ColR/G/B: 00 .. ff = 0 .. 256)
      • 33 05 15 01 ColR ColG ColB 00 00 00 00 00 ID1 ID2 00 00 00 00 00 XORChecksum
      Intensität Ändern: (Int: 00 .. 64 = 0..100%)
      • 33 05 15 02 Int ID1 ID2 00 00 00 00 00 00 00 00 00 00 00 00 XORChecksum
      Zuletzt geändert von MarkusCosi; 27.11.2024, 09:44.

      Kommentar

      • kouzinger
        Azubi
        • 01.12.2025
        • 1

        #4
        Wow. Ich lese viel und kommentiere wenig. Aber an dieser Stelle: Vielen Dank und Respekt für deine aufwendigen Recherchen und das Teilen deiner Ergebnisse. Ich werde es hoffentlich zur Erhellung meiner Weihnachtszeit nutzen können ;-)

        Kommentar

        • Koty007
          Azubi
          • 16.10.2023
          • 7

          #5
          Great. Is it now possible to share the template in Config?

          Kommentar

          • MarkusCosi
            LoxBus Spammer
            • 28.09.2023
            • 369

            #6
            Kleiner Nachtrag:

            Es scheint Lampen von Govee zu geben, bei denen die BLE Kommunikation verschlüsselt ist. Ein Beispiel ist die Lichterkette H7025. Hier sind über den BLE sniffing Ansatz per Wireshark und iPhone leider keine Befehle auslesbar / erkennbar.

            Dennoch: BLE-Befehle können über die "ptReal-Schnittstelle" per lokaler LAN API wie gewohnt unverschlüsselt an die Lampe gesendet werden und funktionieren. Die für die spezifische Lampe gültigen Befehle lassen sich nur eben nicht mehr systematisch herausfinden. Die generischen An/Aus Befehle funktionieren trotzdem. Man kann aber einfach für ähnliche Lampen in der Liste (link) Befehle ausprobieren und so passende für z.B. gewünschte Szenen finden.

            Außerdem habe ich gelernt: Anschalten geht bei manchen Lampen nur per Color-Befehl, also z.B. {"msg":{"cmd":"colorwc","data":{"color": <v>,"colorTemInKelvin":0}}}; v={"r":R,"g":G,"b":B}

            Für die konkrete Lichterkette (H7025) fand ich heraus, dass die Segmentsteuerung = Pixel-Steuerung wie für die Stehlampe (H6076) funktioniert... Und Szenen über Multi-packet a3-Befehle konnte ich auch passende in der Liste finden, e.g für Aurora wie für "RGBIC_Strip": ["owABCQIEI0AAAAECAf8ZA8IKA+I=","owEC5jIED/8ICwf/B/j//wbpAGs=","owIC+AEAgAAjQgAAAQAB/xgDu+Q=","owMKA4LnMgT/03LLhf8NS/9S/wE=","owSZEgHNAAPkACNEAAABAAH/GIc=","owUDuwoDAuUyBAsH/w//CP8G6d0=","owYH+P8QAcwBAIAAJkYAAAEAAZk=","owf/GAO7CgMC5TIFB/j/Cwf//y4=","o/8G6Q//CNz/ERIB3QEAgAAAADY=","MwUE8QgAAAAAAAAAAAAAAAAAAMs="]
            Zuletzt geändert von MarkusCosi; 08.03.2026, 19:57.

            Kommentar

            Lädt...