[74_XiaomiBTLESens.pm] Xiaomi Bluetooth Sensoren FlowerSens/Thermometer

Begonnen von CoolTux, 11 Januar 2018, 15:42:45

Vorheriges Thema - Nächstes Thema

t1me2die

Habe soeben noch einmal die RAW Datei mir vom GitHub geholt.
Evtl. ist mir gestern beim kopieren ein Fehler entstanden, ich werde es weiter beobachten!

Aktueller Logauszug, Werte passen!

2019.10.12 08:04:32 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - Run CreateParamGatttool with mod: read
2019.10.12 08:04:32 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - Read XiaomiBTLESens_ExecGatttool_Run wz_Xiaomi_Sensor_unten|58:2D:34:10:4C:FA|read|0x1e
2019.10.12 08:04:32 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: call gatttool with command: gatttool -i hci0 -b 58:2D:34:10:4C:FA --char-read -a 0x1e 2>&1 /dev/null and loop 0
2019.10.12 08:04:39 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: gatttool loop result Characteristic value/descriptor,05 08 b2 00 88 02

2019.10.12 08:04:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: gatttool result Characteristic value/descriptor,05 08 b2 00 88 02

2019.10.12 08:04:39 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Done: gatttool return string: wz_Xiaomi_Sensor_unten|58:2D:34:10:4C:FA|ok|read|0x1e|{"gtResult":"05 08 b2 00 88 02 "}
2019.10.12 08:04:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ProcessingNotification
2019.10.12 08:04:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ProcessingNotification: handle 0x1e
2019.10.12 08:04:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - Clear Grass Sens Handle0x1e
2019.10.12 08:04:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - WriteReadings: Readings were written


Ich habe das Device noch einmal gelöscht und neu angelegt, wieder liest er mit einem falschen handle:

2019.10.12 08:08:10 3: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - defined with BTMAC 58:2D:34:10:4C:FA
2019.10.12 08:09:37 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - Run CreateParamGatttool with mod: read
2019.10.12 08:09:37 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - Read XiaomiBTLESens_ExecGatttool_Run wz_Xiaomi_Sensor_unten|58:2D:34:10:4C:FA|read|0x3a
2019.10.12 08:09:37 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: call gatttool with command: gatttool -i hci0 -b 58:2D:34:10:4C:FA --char-read -a 0x3a 2>&1 /dev/null and loop 0
2019.10.12 08:09:39 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: gatttool loop result Characteristic value/descriptor,02 3b 00 14 00

2019.10.12 08:09:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Run: gatttool result Characteristic value/descriptor,02 3b 00 14 00

2019.10.12 08:09:39 5: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ExecGatttool_Done: gatttool return string: wz_Xiaomi_Sensor_unten|58:2D:34:10:4C:FA|ok|read|0x3a|{"gtResult":"02 3b 00 14 00 "}
2019.10.12 08:09:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - ProcessingNotification
2019.10.12 08:09:39 4: XiaomiBTLESens (wz_Xiaomi_Sensor_unten) - WriteReadings: Readings were written

CoolTux

0x3a ist das Batterie Handle. War wohl noch falsch, ich sehe in Deinen alten Posts ein 0x3b wäre das richtiger?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Vergiss es, ich hatte vergessen es im Hash an zu passen. Überall sonst hatte ich es schon gemacht.

Habe ich korrigiert. Bitte noch mal neu von Github holen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

t1me2die

Aktuell schaut es gut aus, ich beobachte es weiter!

List vom Device

Internals:
   BTMAC      58:2D:34:10:4C:FA
   CFGFN     
   DEF        58:2D:34:10:4C:FA
   FUUID      5da1bc59-f33f-5bc8-2ca8-407cc6b85fdec1b0
   INTERVAL   300
   NAME       wz_Xiaomi_Sensor_unten
   NOTIFYDEV  global,wz_Xiaomi_Sensor_unten
   NR         3725
   NTFY_ORDER 50-wz_Xiaomi_Sensor_unten
   STATE      T: 18.3 H: 68.2
   TYPE       XiaomiBTLESens
   VERSION    v2.7.60
   loglevel   4
   READINGS:
     2019-10-12 13:43:43   batteryPercent  77
     2019-10-12 13:43:43   batteryState    ok
     2019-10-12 13:43:31   firmware        1.1.2_0020
     2019-10-12 13:43:43   humidity        68.2
     2019-10-12 13:43:43   state           T: 18.3 H: 68.2
     2019-10-12 13:43:43   temperature     18.3
   helper:
     CallBattery 0
     CallSensDataCounter 0
     updateTimeCallBattery 1570880623.27938
     updateTimestampCallBattery 2019-10-12 13:43:43
Attributes:
   model      clearGrassSens
   room       XiaomiBTLESens

CoolTux

Wäre ja super wenn das passt.
Muss gestehen Dank Dir ist das doch Recht schnell lauffähig geworden. Danke für Deine tolle Arbeit.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

t1me2die

Gar kein Problem, es lag ja auch in meinem Interesse.

Zu dem Thema Battery konnte ich folgendes finden:
https://github.com/hannseman/homebridge-mi-hygrothermograph/issues/65

Angeblich wird die Kapazität nicht in den BT handles übermittelt, dass würde erklären, warum ich auch keinen %-Wert in der App finde.
Ich wollte eben eine neue Batterie einsetzen, aber eine CR2430 habe ich hier nicht liegen.
Habe nur CR2032 liegen... Wieder so ein Spezialfall.

Was mir aufgefallen ist, nachdem ich die Batterie einmal draußen hatte und neu eingesetzt habe, waren die handle's zuerst für die Katz!
Nach dem ich die App geöffnet habe, waren die handles alles wieder korrekt.

Ich werde das trotzdem weiterhin beobachten, habe mir ja alle handle's notiert und kann bei Veränderungen die HEX Werte analysieren.
Ich melde mich, falls mir was auffällt.

Gestern habe ich angefangen den Xiaomi e-Ink LYWSD02MMC zu analysieren. Dummerweise hat das Teil handles von 0x01 - 0x70... Haufenweise handle's, wo sich irgendwo die Werte wohl drin verstecken. Wahrscheinlich ist auch irgendwo die Uhrzeit versteckt, mal schauen was ich finden kann...

Gruß

t1me2die

Moin Leon,

vielleicht hast du paar hilfreiche Tipps für mich.
Am WE habe ich mich ausgiebig mit dem Xiaomi "LYWSD02" beschäftigt.
Zuerst habe ich erstmal alle handle's aufgelistet und mir die HEX Werte übersetzen lassen.
Nach ASCII kam dabei nicht viel brauchbares raus, dass war ich vom ClearGrass ja schon gewohnt.
Aus diesem Grund habe ich direkt die decimal-Werte betrachtet, ohne die passende Werte zu finden.

Nach ein wenig googeln habe ich festgestellt, dass es schon Lösungen für Home Assistant / OpenMQTT geben soll.
Ich habe mir mal den Code von OpenMQTT angeschaut unter: https://github.com/1technophile/OpenMQTTGateway/blob/development/main/ZgatewayBT.ino

Dort konnte ich das o.g. Modell auch finden, kleiner Codeausschnitt:

                  pos = strpos(service_data,"205b04");
                  if (pos != -1){
                    trc(F("LYWSD02 data reading"));
                    //example "servicedata":"70205b04b96ab883c8593f09041002e000"
                    #ifdef ZmqttDiscovery
                      if(!isDiscovered(mac)) LYWSD02Discovery(mac);
                    #endif
                    process_sensors(pos - 24,service_data,mac);
                  }


In diesem example wird mit einer "servicedata" gearbeitet, sowas war mir neu.
Ich habe nämlich vergebens nach handle's gesucht...
Diese "servicedata" erinnerte mich aber an das Beispiel vom ClearGrass, wo es auch eine gute Dokumentation / Erläuterung gab (https://github.com/alexvenom/XiaomiCleargrassInkDislpay/blob/master/XiaomiClearGrassInk.js)
Ich habe also versucht hier irgendwelche Ähnlichkeiten zu erkennen.

Da ich aber nicht wirklich weiter kam, habe ich mich mit "bluetoothctl" befasst und folgendes "erreicht"...

[bluetooth]# info E7:2E:00:E2:74:D6
Device E7:2E:00:E2:74:D6
        Name: LYWSD02
        Alias: LYWSD02
        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: Xiaomi Inc.               (0000fe95-0000-1000-8000-00805f9b34fb)
        UUID: Dialog Semiconductor GmbH (0000fef5-0000-1000-8000-00805f9b34fb)
        UUID: Vendor specific           (2b43ccc0-2506-415c-a16c-e4cc5f52ef78)
        UUID: Vendor specific           (aaaaaaa0-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
        UUID: Vendor specific           (ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6)
        UUID: Vendor specific           (fafafa00-fafa-fafa-fafa-fafafafafafa)
        ServiceData Key: 0000fe95-0000-1000-8000-00805f9b34fb
        ServiceData Value: 0x70
        ServiceData Value: 0x20
        ServiceData Value: 0x5b
        ServiceData Value: 0x04
        ServiceData Value: 0x5d
        ServiceData Value: 0xd6
        ServiceData Value: 0x74
        ServiceData Value: 0xe2
        ServiceData Value: 0x00
        ServiceData Value: 0x2e
        ServiceData Value: 0xe7
        ServiceData Value: 0x09
        ServiceData Value: 0x06
        ServiceData Value: 0x10
        ServiceData Value: 0x02
        ServiceData Value: 0xee
        ServiceData Value: 0x02


Nun habe ich begonnen die ServiceData Value zu analysieren, ich dachte mir, dass sich hier die Werte verstecken müsste, leider wurde ich auch hier nicht fündig.
Als ich mir die Werte näher angeschaut habe, viel mir auf, dass es sich hier um den servicedata String handeln könnte.
Es kam also folgendes raus:

70205b045dd674e2002ee709061002ee02


In diesem String fand ich dann auch eine direkte Ähnlichkeit zu dem o.g. Quellcode:
pos = strpos(service_data,"205b04");

Ich schaute mir also weiter den String an und unterteilte ihn für mich wie folgt:

70 205b04 5d d674e2002ee7 09061002ee02
205b04 = indikator für das Modell
d674e2002ee7 = reverse MAC -> E7:2E:00:E2:74:D6
70 = ???
5d = ???
09061002ee02 = ???


Mit den restlichen Werten wusste ich nicht, was ich anfangen sollte.

Ich habe mir nun OpenMQTT weitere angeschaut.
Ein Teil der servicedata wird zuerst an eine Routine "process_sensors" gegeben, kurz danach wird die servicedate an "value_from_service_data" weitergegeben.
Wenn ich es richtig verstehe werden hier irgendwelche HEX Werte umgedreht.


double value_from_service_data(char * service_data, int offset, int data_length){
  char rev_data[data_length+1];
  char data[data_length+1];
  memcpy( rev_data, &service_data[offset], data_length );
  rev_data[data_length] = '\0';
 
  // reverse data order
  revert_hex_data(rev_data, data, data_length+1);
  double value = strtol(data, NULL, 16);
  if (value > 65000 && data_length <= 4) value = value - 65535;
  trc(value);
  return value;
}


Kurz danach wird mithilfe von value irgendein hum/temp Wert ermittelt.

  // Mi flora provides tem(perature), (earth) moi(sture), fer(tility) and lux (illuminance)
  // Mi Jia provides tem(perature), batt(erry) and hum(idity)
  // following the value of digit 47 we determine the type of data we get from the sensor
  switch (rest_data[47 + offset]) {
    case '9' :
          BLEdata.set("fer", (double)value);
    break;
    case '4' :
          BLEdata.set("tem", (double)value/10);
    break;
    case '6' :
          BLEdata.set("hum", (double)value/10);
    break;
    case '7' :
          BLEdata.set("lux", (double)value);
     break;
    case '8' :
          BLEdata.set("moi", (double)value);
     break;
     
    case 'a' :
          BLEdata.set("batt", (double)value);
     break;

     case 'd' :
          // humidity
          value = value_from_service_data(rest_data, 52 + offset, 4);
          BLEdata.set("tem", (double)value/10);
          // temperature
          value = value_from_service_data(rest_data, 56 + offset, 4);
          BLEdata.set("hum", (double)value/10);
     break;


Und nun brauche ich einen Ratschlag / Tipp von Dir, was ich als nächstes machen soll  ::)

Gruß
Mathze

t1me2die

So Leon, ich bin soweit...

Schlechte Nachricht, via gatttool kam ich diesmal nicht so recht an die Daten, dafür aber mit "bluetoothctl"
Das Modell "LYWSD02" speichert seine Werte für Temperatur und Luftfeuchtigkeit in einer Servicedata.

Wie erhalte ich die Servicedata?

root@raspberrypi:~# bluetoothctl
[bluetooth]# info E7:2E:00:E2:74:D6
Device E7:2E:00:E2:74:D6
Name: LYWSD02
Alias: LYWSD02
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: Xiaomi Inc.               (0000fe95-0000-1000-8000-00805f9b34fb)
UUID: Dialog Semiconductor GmbH (0000fef5-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific           (2b43ccc0-2506-415c-a16c-e4cc5f52ef78)
UUID: Vendor specific           (aaaaaaa0-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
UUID: Vendor specific           (ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6)
UUID: Vendor specific           (fafafa00-fafa-fafa-fafa-fafafafafafa)
ServiceData Key: 0000fe95-0000-1000-8000-00805f9b34fb
ServiceData Value: 0x70
ServiceData Value: 0x20
ServiceData Value: 0x5b
ServiceData Value: 0x04
ServiceData Value: 0x88
ServiceData Value: 0xd6
ServiceData Value: 0x74
ServiceData Value: 0xe2
ServiceData Value: 0x00
ServiceData Value: 0x2e
ServiceData Value: 0xe7
ServiceData Value: 0x09
ServiceData Value: 0x06
ServiceData Value: 0x10
ServiceData Value: 0x02
ServiceData Value: 0xa8
ServiceData Value: 0x02
[bluetooth]#


Hier siehst du ganz viele ServiceData Value, zum besseren Verständnis:

70 205b04 88 d674e2002ee7 0906 1002 a802

205b04 = signalisiert uns, dass es sich um das Modell LYWSD02 handelt
d674e2002ee7 = MAC umgedreht
0906 = die "6" bedeutet, dass sich in dieser ServiceData die Luftfeuchtigkeit befindet
A802 = 2A8 = 68% Luftfeuchtigkeit


So, jetzt benötigen wir noch die Temperatur, diese befindet sich auch in einer ServiceData.

[bluetooth]# info E7:2E:00:E2:74:D6
Device E7:2E:00:E2:74:D6
Name: LYWSD02
Alias: LYWSD02
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: Xiaomi Inc.               (0000fe95-0000-1000-8000-00805f9b34fb)
UUID: Dialog Semiconductor GmbH (0000fef5-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific           (2b43ccc0-2506-415c-a16c-e4cc5f52ef78)
UUID: Vendor specific           (aaaaaaa0-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
UUID: Vendor specific           (ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6)
UUID: Vendor specific           (fafafa00-fafa-fafa-fafa-fafafafafafa)
ServiceData Key: 0000fe95-0000-1000-8000-00805f9b34fb
ServiceData Value: 0x70
ServiceData Value: 0x20
ServiceData Value: 0x5b
ServiceData Value: 0x04
ServiceData Value: 0x03
ServiceData Value: 0xd6
ServiceData Value: 0x74
ServiceData Value: 0xe2
ServiceData Value: 0x00
ServiceData Value: 0x2e
ServiceData Value: 0xe7
ServiceData Value: 0x09
ServiceData Value: 0x04
ServiceData Value: 0x10
ServiceData Value: 0x02
ServiceData Value: 0xd4
ServiceData Value: 0x00


Hier siehst du ganz viele ServiceData Value, zum besseren Verständnis:

70 205b04 03 d674e2002ee7 0904 1002 d400

205b04 = signalisiert uns, dass es sich um das Modell LYWSD02 handelt
d674e2002ee7 = MAC umgedreht
0904 = die "4" bedeutet, dass sich in dieser ServiceData die Temperatur befindet
d4 =  212 = 21.2°C


Um diese Werte zu erhalten, muss man innerhalb von "bluetoothctl" den Befehl
scan on
starten. Nach kurzer Zeit 1-2Sekunden trudeln dann die aktuellen info's von sämtlichen Devices auf.
Mit einem
scan off
hält man den Vorgang an und schaut sich danach die Werte von dem gewünschten Device via
info MAC
in meinem Beispiel: info E7:2E:00:E2:74:D6

an. Nun bastelt man sich die ServiceData zusammen und schaut auf folgende Stellen:

#my $serviceData = '70205b0488d674e2002ee709061002a802';   #Luftfeuchtigkeit
my $serviceData = '70205b0403d674e2002ee709041002d400';    #Temperatur

# pruefe, ob es sich bei dem Modell um einen LYWSD02 handel
if (substr($serviceData,2,6) eq '205b04')
{   # pruefe, welcher Wert sich in der ServiceData befindet
    # 4 = Temperatur
    # 6 = Luftfeuchtigkeit
    if (substr($serviceData, 25, 1) eq '4')
    {   my $temperatur = substr($serviceData,30,2);
        print hex($temperatur)/10;
    }
    elsif (substr($serviceData, 25, 1) eq '6')
    {   my $humidity = substr($serviceData,32,2) .substr($serviceData,30,2);
        print hex($humidity)/10;
    }
}


Mit folgendem handle bekommst du die Firmware:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x14
Characteristic value/descriptor: 31 2e 31 2e 32 5f 30 30 34 32
Übersetzt nach ASCII: 1.1.2_0042


Mit folgendem handle bekommst du den Hersteller:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x0c
Characteristic value/descriptor: 6d 69 61 6f 6d 69 61 6f 63 65 2e 63 6f 6d
Übersetzt nach ASCII: miaomiaoce.com


Mit folgendem handle bekommst du das Modell:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x0e
Characteristic value/descriptor: 4c 59 57 53 44 30 32
Übersetzt nach ASCII: LYWSD02


Mit folgendem handle bekommst du die Uhrzeit + Datum:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x3e
Characteristic value/descriptor: db f6 a5 5d 02

Inverted: 5da5f6db
Ergebnis: 15.10.2019 18.42.3

Quellcode zum umwandeln des inverted Hex-Wertes

my $string = '5da5f6db';
my $time = hex($string);

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime( $time );
$mon  += 1;
$year += 1900;

printf "%s.%s.%s %s.%s.%s\n", $mday, $mon, $year, $hour, $min, $sec;


So, nun die Frage, möchtest du das in deinem Modul hinzu programmieren oder soll ich versuchen daraus ein eigenes Modul zu gießen?
Der Ablauf bzgl. "bluetoothctl" ist ja schon ein anderer, wie du ihn z.Z. machst.

Gruß
Mathze

CoolTux

Zitat von: t1me2die am 15 Oktober 2019, 18:34:21
So Leon, ich bin soweit...

Schlechte Nachricht, via gatttool kam ich diesmal nicht so recht an die Daten, dafür aber mit "bluetoothctl"
Das Modell "LYWSD02" speichert seine Werte für Temperatur und Luftfeuchtigkeit in einer Servicedata.

Wie erhalte ich die Servicedata?

root@raspberrypi:~# bluetoothctl
[bluetooth]# info E7:2E:00:E2:74:D6
Device E7:2E:00:E2:74:D6
Name: LYWSD02
Alias: LYWSD02
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: Xiaomi Inc.               (0000fe95-0000-1000-8000-00805f9b34fb)
UUID: Dialog Semiconductor GmbH (0000fef5-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific           (2b43ccc0-2506-415c-a16c-e4cc5f52ef78)
UUID: Vendor specific           (aaaaaaa0-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
UUID: Vendor specific           (ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6)
UUID: Vendor specific           (fafafa00-fafa-fafa-fafa-fafafafafafa)
ServiceData Key: 0000fe95-0000-1000-8000-00805f9b34fb
ServiceData Value: 0x70
ServiceData Value: 0x20
ServiceData Value: 0x5b
ServiceData Value: 0x04
ServiceData Value: 0x88
ServiceData Value: 0xd6
ServiceData Value: 0x74
ServiceData Value: 0xe2
ServiceData Value: 0x00
ServiceData Value: 0x2e
ServiceData Value: 0xe7
ServiceData Value: 0x09
ServiceData Value: 0x06
ServiceData Value: 0x10
ServiceData Value: 0x02
ServiceData Value: 0xa8
ServiceData Value: 0x02
[bluetooth]#


Hier siehst du ganz viele ServiceData Value, zum besseren Verständnis:

70 205b04 88 d674e2002ee7 0906 1002 a802

205b04 = signalisiert uns, dass es sich um das Modell LYWSD02 handelt
d674e2002ee7 = MAC umgedreht
0906 = die "6" bedeutet, dass sich in dieser ServiceData die Luftfeuchtigkeit befindet
A802 = 2A8 = 68% Luftfeuchtigkeit


So, jetzt benötigen wir noch die Temperatur, diese befindet sich auch in einer ServiceData.

[bluetooth]# info E7:2E:00:E2:74:D6
Device E7:2E:00:E2:74:D6
Name: LYWSD02
Alias: LYWSD02
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: Xiaomi Inc.               (0000fe95-0000-1000-8000-00805f9b34fb)
UUID: Dialog Semiconductor GmbH (0000fef5-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific           (2b43ccc0-2506-415c-a16c-e4cc5f52ef78)
UUID: Vendor specific           (aaaaaaa0-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
UUID: Vendor specific           (ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6)
UUID: Vendor specific           (fafafa00-fafa-fafa-fafa-fafafafafafa)
ServiceData Key: 0000fe95-0000-1000-8000-00805f9b34fb
ServiceData Value: 0x70
ServiceData Value: 0x20
ServiceData Value: 0x5b
ServiceData Value: 0x04
ServiceData Value: 0x03
ServiceData Value: 0xd6
ServiceData Value: 0x74
ServiceData Value: 0xe2
ServiceData Value: 0x00
ServiceData Value: 0x2e
ServiceData Value: 0xe7
ServiceData Value: 0x09
ServiceData Value: 0x04
ServiceData Value: 0x10
ServiceData Value: 0x02
ServiceData Value: 0xd4
ServiceData Value: 0x00


Hier siehst du ganz viele ServiceData Value, zum besseren Verständnis:

70 205b04 03 d674e2002ee7 0904 1002 d400

205b04 = signalisiert uns, dass es sich um das Modell LYWSD02 handelt
d674e2002ee7 = MAC umgedreht
0904 = die "4" bedeutet, dass sich in dieser ServiceData die Temperatur befindet
d4 =  212 = 21.2°C


Um diese Werte zu erhalten, muss man innerhalb von "bluetoothctl" den Befehl
scan on
starten. Nach kurzer Zeit 1-2Sekunden trudeln dann die aktuellen info's von sämtlichen Devices auf.
Mit einem
scan off
hält man den Vorgang an und schaut sich danach die Werte von dem gewünschten Device via
info MAC
in meinem Beispiel: info E7:2E:00:E2:74:D6

an. Nun bastelt man sich die ServiceData zusammen und schaut auf folgende Stellen:

#my $serviceData = '70205b0488d674e2002ee709061002a802';   #Luftfeuchtigkeit
my $serviceData = '70205b0403d674e2002ee709041002d400';    #Temperatur

# pruefe, ob es sich bei dem Modell um einen LYWSD02 handel
if (substr($serviceData,2,6) eq '205b04')
{   # pruefe, welcher Wert sich in der ServiceData befindet
    # 4 = Temperatur
    # 6 = Luftfeuchtigkeit
    if (substr($serviceData, 25, 1) eq '4')
    {   my $temperatur = substr($serviceData,30,2);
        print hex($temperatur)/10;
    }
    elsif (substr($serviceData, 25, 1) eq '6')
    {   my $humidity = substr($serviceData,32,2) .substr($serviceData,30,2);
        print hex($humidity)/10;
    }
}


Mit folgendem handle bekommst du die Firmware:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x14
Characteristic value/descriptor: 31 2e 31 2e 32 5f 30 30 34 32
Übersetzt nach ASCII: 1.1.2_0042


Mit folgendem handle bekommst du den Hersteller:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x0c
Characteristic value/descriptor: 6d 69 61 6f 6d 69 61 6f 63 65 2e 63 6f 6d
Übersetzt nach ASCII: miaomiaoce.com


Mit folgendem handle bekommst du das Modell:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x0e
Characteristic value/descriptor: 4c 59 57 53 44 30 32
Übersetzt nach ASCII: LYWSD02


Mit folgendem handle bekommst du die Uhrzeit + Datum:

root@raspberrypi:~# gatttool -b E7:2E:00:E2:74:D6 --char-read -a 0x3e
Characteristic value/descriptor: db f6 a5 5d 02

Inverted: 5da5f6db
Ergebnis: 15.10.2019 18.42.3

my $string = '5da5f6db';
my $time = hex($string);

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
    localtime( $time );
$mon  += 1;
$year += 1900;

printf "%s.%s.%s %s.%s.%s\n", $mday, $mon, $year, $hour, $min, $sec;


So, nun die Frage, möchtest du das in deinem Modul hinzu programmieren oder soll ich versuchen daraus ein eigenes Modul zu gießen?
Der Ablauf bzgl. "bluetoothctl" ist ja schon ein anderer, wie du ihn z.Z. machst.

Gruß
Mathze

Hallo,

Und man bekommt die Daten ganz sicher nicht mit gatttool? Wenn es wirklich nur so geht wie Du schreibst kann ich es nicht einbauen ins Modul. Dann muss man was eigenes machen, wobei das wegen der interaktiven Interaktion schwer wird. Da wirst Du versuchen müssen mit dem neuen SubProcesses von Andre zu arbeiten. Habe ich aber noch keine Erfahrung mit gesammelt.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

t1me2die

Ich konnte via gatttool diese serviceData nicht finden.
Ich bin mehrmals alle handle's durchgegangen, evtl. muss ich erst via write irgendein handle beschreiben, bevor er mir die Daten auf diesen Weg ausspuckt, jedoch finde ich nirgendwo diesbezüglich eine Anleitung.
Die Module, die es z.B. für ioBroker oder HA gibt, verwenden bluepy um die serviceData zu verarbeiten.

Wie ich bei dem Modul starte, weiß ich noch gar nicht.
Ich dachte, ich könnte via Terminal erstmal ein "scan on" ausführen, dieses automatisch fünf Sekunden später wieder stoppen und dann die serviceData (sprich "info MAC") mir irgendwo zwischenspeichern und diese dann auflösen.
Das würde ich dann in einer Schleife machen, solange ich zwei "serviceData" mit den benötigten Werte habe (bzw. die Schleife x-Mal durchlaufen...)

Was sagst du zu der Idee?
Im ersten Step natürlich nur für mich, um mich weitere mit der Materie zu beschäftigen.

Gruß

CoolTux

Ich finde es toll das Du Dich dafür interessierst. Ich sage Dir erstmal weiter nichts dazu weil ich Dich erstens nicht verschrecken möchte und zweitens ich der Meinung bin alleine rausfinden ist meist besser.

Was Modulprogrammierung an geht
https://wiki.fhem.de/wiki/Kategorie:Development


Probiere es einfach aus. Du kannst auch erstmal nur den Code in eine 99_myUtils schreiben und schauen was passiert.
Wenn Du Fragen hast schreib mir einfach Mail.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

t1me2die

Danke für deine Hilfe, ich werde darauf zurückkommen!
Gerade im Bezug auf die Modulprogrammierung stehe ich ganz am Anfang, mir fehlen halt sehr viele Basics...

Ich habe nun aber erstmal mit einem myUtils Programm angefangen, natürlich blocking  ;D
Aber das kommt alles mit der Zeit.

Aktuell bekomme ich mit Hilfe der myUtils schon eimal das Ergebnis in die Logdatei geschrieben.
Als Übergabe verwende ich die MAC Adresse.

{ myUtils_LYWSD02_main("E7:2E:00:E2:74:D6") }


Als Ergebnis bekomme ich, falls es klappt und kein Timeout in die Quere kommt:

2019.10.16 16:05:28 1: Temperatur      : 19.2 Grad
2019.10.16 16:06:02 1: Luftfeuchtigkeit: 74 %


Für's erste bin ich zufrieden...

Ich nutze:

use IPC::Open2;
use IO::Select;

um die Werte von dem Terminal mir in einen "buffer" zu schreiben.
In dem Buffer befindet sich eine Zeile, genauso wie man sie im Terminalfenster auch sieht.
Diesen Buffer pruefe ich dann gegen die übergebene MAC Adresse und hole mir die benötigten ServiceData Values.
Diese wandle ich dann nur noch um und schon kann ich das Ergebnis schreiben.

Gruß
Mathze

CoolTux

Das klingt doch schon mal super. Jetzt nur noch BlockingCall anschauen und dann sollte es auch nonBlocking gehen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

t1me2die

Hab mich eben mal direkt an deinem Code entlang gearbeitet.

BlockingCall konnte ich so auch sehr fix einbauen.
Hatte Anfangs Probleme ein Array zu übergeben, dass Problem konnte ich nun auch meistern...
Nun reicht es für heute auch erstmal, mein Kopf glüht...


2019.10.16 16:49:41 1: Start der Routine
2019.10.16 16:49:41 1: Mac -> E7:2E:00:E2:74:D6
2019.10.16 16:49:41 1: ARGV -> scan on scan off quit
2019.10.16 16:49:55 1: Temperatur      : 19.2 Grad
2019.10.16 16:49:58 1: Luftfeuchtigkeit: 74 %


PS.: gatttool fliegt auf die Nase, wenn ich mit "bluetoothctl" arbeite, was für ein Wunder  :P

PPS.:

2019.10.16 16:54:55 1: ERROR evaluating {FHEM::XiaomiBTLESens::ExecGatttool_Done('wz_Flower_Sensor_Schefflera|C4:7C:8D:6A:39:7E|ok|read|0x35|{"gtResult":"aa bb cc dd ee ff 99 88 77 66 00 00 00 00 00 00 "}')}: Can't use string ("1") as a HASH ref while "strict refs" in use at ./FHEM/74_XiaomiBTLESens.pm line 1163.

t1me2die

Ich konnte die Finger doch nicht still halten, die Readings wollte ich noch ins Device bekommen, nun reicht es aber für's erste  :)


Internals:
   BTMAC      E7:2E:00:E2:74:D6
   CFGFN     
   DEF        E7:2E:00:E2:74:D6
   FUUID      5da765ad-f33f-5bc8-54c2-a012f4788159ef04
   INTERVAL   300
   NAME       wz_Xiaomi_eInk
   NR         57
   NTFY_ORDER 50-wz_Xiaomi_eInk
   STATE      T: 19.3 H: 74
   TYPE       XiaomiEInk
   VERSION    v0.1.0
   loglevel   4
   READINGS:
     2019-10-16 21:37:19   humidity        74
     2019-10-16 21:37:19   state           T: 19.3 H: 74
     2019-10-16 21:37:19   temperature     19.3
Attributes:
   room       XiaomiEInk


Danke für deinen Code  :D
Sehr hilfreich!