Neues Modul: 74_BleTagBattery - Batterie Informationen für BLE Tags

Begonnen von mumpitzstuff, 27 Februar 2017, 21:29:50

Vorheriges Thema - Nächstes Thema

mumpitzstuff

Mich hat es etwas frustriert, das es keine vernünftige Anzeige des Batteriestandes für BLE Tags gibt. Im Wiki oder Forum habe ich nur irgendwelche Skripte gefunden, die ich mir nur ungern mühsam installieren wollte. Ich habe deshalb ein sehr einfaches Modul geschrieben, das als Endanwender extrem einfach installiert werden kann und danach ohne weitere Konfiguration die BLE Tags absolut automatisch (alle 6h) um das Reading batteryLevel ergänzt.
Momentan werden lediglich die unten angegebenen Tags unterstützt, ich würde aber die Liste gern mit eurer Hilfe erweitern. Dazu benötige ist ein Listing eures Tags und wenn möglich die Information, mit welchem Gatttool Aufruf man bei diesem Tag den Zustand der Batterie auslesen kann.

Falls etwas nicht funktionieren sollte, dann aktiviert im device verbose 5 und schickt mir den relevanten Teil des Logfiles zu.

V0.0.3
BleTagBattery - Update batteryLevel for all BLE tags

This module can be used to update the Reading batteryLevel and battery  for all bluetooth low energy tags registered as PRESENCE devices.

Requirements:

  • Gattool is required to use this module. Be sure that bluez is installed (sudo apt-get install bluez).
  • BLE tags must be registered as PRESENCE devices of type lan-bluetooth.


Installation:

Usage:
The module automatically try to reach all BLE tags every 6 hours and to update the reading batteryLevel and battery for each tag directly within the tag device. You can manually trigger the update with: set <name of device> statusRequest.


Supported BLE tags:

  • should work for all BLE tags now

GitHub: https://github.com/mumpitzstuff/fhem-BleTagBattery

binford6000

 
ZitatIm Wiki oder Forum habe ich nur irgendwelche Skripte gefunden, die ich mir nur ungern mühsam installieren wollte.

Hallo mumpitzstuff,
mir geht es genauso. Habe alle Scripts usw. ausprobiert aber leider ohne Erfolg.
Der gtag selbst arbeitet natürlich ohne Probleme!

Also ich habe alles installiert und eingerichtet und werde dann nachher sehen ob Dein Modul funktioniert.
Kann man das Intervall von 6h ändern? Vielleicht über ein attr? Alle 24h würde ja auch gebnügen  ;)

Mit
set <device> StatusRequest
kann ich ja auch ein Update erzwingen...

VG Sebastian

knopf_piano

ich hab die response des gatttools per split den battLevel in ein userReading geschrieben.
das ganze erfolgt zyklisch alle 6h bei presence des devices, bzw bei absent->present. is bei mir ne kleine func in 99_myUtils in zusammenspiel mit dem notity/at.
zotac nano mit proxmox und ganz viel zeug drauf

mumpitzstuff

Ich habe den Zyklus 6h bewusst gewählt, ich kann aber auch ein Attribut hinzufügen. Aber Vorsicht bei 24h. Wenn man nicht den Zeitpunkt wählen kann, dann kann es passieren, das die Abfrage immer passiert wenn du auf Arbeit bist und du wirst gar nichts sehen.
Ich muss auch noch ein paar Hinweise geben, was im Zusammenspiel mit lepresenced zu beachten ist. Hier braucht man entweder einen zweiten Dongle ( beste Lösung) oder man bekommt eventuell Probleme ( kann auch gut gehen), da sich lepresenced und gatttool in die Quere kommen. Hier kann es helfen das Sleep im lepresenced deamon von 1 auf z.b. 2-5s zu erhöhen (direkt im Script editieren). 

mumpitzstuff

Zitat von: knopf_piano am 02 März 2017, 17:31:55
ich hab die response des gatttools per split den battLevel in ein userReading geschrieben.
das ganze erfolgt zyklisch alle 6h bei presence des devices, bzw bei absent->present. is bei mir ne kleine func in 99_myUtils in zusammenspiel mit dem notity/at.

Ich habe keine Ahnung inwieweit solche Skripte blockierend aufgerufen werden oder nicht. Das Modul arbeitet nicht blockierend. Ich hab auch diverse Skripte gefunden, welche mal das und mal das erfordern oder nur mit Aufwand funktionieren (siehe wiki). Ich wollte deshalb mal alles unter einen Hut bringen und als klicki bunti Lösung anbieten.

knopf_piano

Passt, meins funzt, bin damit zufrieden. Ich schau mir deins mal an.
aber wie geschrieben wird bei mir der level auch bei absent->present eingeholt. Also zusätzlich zum zyklus. Schau mal ob du das auch abdecken kannst. Bin grad auf piste, also mehr oder weniger offline, kann nix anguggn oder probieren ;-)
zotac nano mit proxmox und ganz viel zeug drauf

binford6000

Also bei mir tut es leider nicht...

Hier das BleTagBattery Device:

Internals:
   CFGFN
   NAME       gtag_battery
   NR         812
   STATE      active
   TYPE       BleTagBattery
   VERSION    0.0.2
   Readings:
     2017-03-02 19:37:40   state           active
   Helper:
Attributes:
   alias      Batterie Status BLE-Geräte
   group      Anwesenheit
   icon       measure_battery_75
   room       Hardware
   verbose    5


Und hier der gtag selbst:

Internals:
   ADDRESS    7C:2F:80:98:AC:0F
   DEF        lan-bluetooth 7C:2F:80:98:AC:0F localhost:5333 60
   DeviceName localhost:5333
   FD         31
   MODE       lan-bluetooth
   NAME       Sebastian.gtag.PRE
   NOTIFYDEV  global
   NR         353
   NTFY_ORDER 50-Sebastian.gtag.PRE
   PARTIAL
   STATE      present
   TIMEOUT_NORMAL 60
   TIMEOUT_PRESENT 60
   TYPE       PRESENCE
   Readings:
     2017-03-02 20:33:49   device_name     Gigaset G-tag
     2017-03-02 20:33:49   presence        present
     2017-03-02 20:33:49   state           present
   Helper:
     CURRENT_STATE present
     CURRENT_TIMEOUT normal
Attributes:
   absenceThreshold 3
   alias      Sebastian's gtag
   devStateIcon present:status_available@green absent:control_building_empty@red
   group      Anwesenheit
   icon       gtag1
   room       Hardware


Im Log steht folgendes:

2017.03.02 20:35:08 4: Sub BleTagBattery_Run (gtag_battery) - start blocking call
2017.03.02 20:35:08 5: Sub BleTagBattery_stateRequest (gtag_battery) - state request called
2017.03.02 20:35:08 4: Sub BleTagBattery_BlockingRun (gtag_battery) - device found. device: Sebastian.gtag.PRE
2017.03.02 20:35:08 4: Sub BleTagBattery_BlockingRun (gtag_battery) - device name: Gigaset G-tag
2017.03.02 20:35:08 4: Sub BleTagBattery_BlockingRun (gtag_battery) - device address: 7C:2F:80:98:AC:0F
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 0, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 1, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 2, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 3, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 4, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 5, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 6, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 7, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 8, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - call gatttool char read loop: 9, result: connect: Connection refused (111)
2017.03.02 20:35:08 4: Sub BleTagBattery_readSensorValue (gtag_battery) - invalid gatttool response
2017.03.02 20:35:08 4: Sub BleTagBattery_BlockingRun (gtag_battery) - processing gatttool response for device Sebastian.gtag.PRE. batteryLevel:
2017.03.02 20:35:09 4: Sub BleTagBattery_BlockingDone (gtag_battery) - set reading batteryLevel of device: Sebastian.gtag.PRE
2017.03.02 20:35:09 4: Sub BleTagBattery_BlockingDone (gtag_battery) - done


Ich meine mich erinnern zu können, dass das Script aus dem Anwesenheits-Wiki auch "Connection refused (111)" zurückgegeben hat...  :(

bluez 5.23-2+rpi2 läuft auf einem aktuellen debian jessie und rpi2.

VG Sebastian



Mumpitz

Müssen vorgängig die alten Scripte deaktiviert oder etwas deinstalliert werden?

mumpitzstuff

#8
Es läuft eigentlich alles wunderbar bei dir, aber da scheint irgendwas den Dongle zu blockieren. Ich habe selbst 2 G-Tags und das Modul läuft dort einwandfrei, allerdings verwende ich 2 Bluetooth Dongles. Einen nur für lepresenced und den zweiten für die Abfrage der Batterie der G-Tags und meiner Pflanzensensoren.
Was hast du sonst noch auf deinem Bluetooth Dongle laufen? Zufällig lepresenced oder irgendwelche anderen Skripte die dauerhaft den Bluetooth Dongle blockieren z.b. mit: hcitool lescan?

So in etwa sollte es aussehen:

2017.03.03 01:03:32 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device found. device: GTAG_ABC
2017.03.03 01:03:32 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device name: Gigaset G-tag
2017.03.03 01:03:32 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device address: FF:EE:DD:CC:BB:AA
2017.03.03 01:03:39 4: Sub BleTagBattery_readSensorValue (BLETAG_BATTERY) - call gatttool char read loop: 0, result: connect error: Function not implemented (38)

2017.03.03 01:03:48 4: Sub BleTagBattery_readSensorValue (BLETAG_BATTERY) - call gatttool char read loop: 1, result: Characteristic value/descriptor: 64

2017.03.03 01:03:48 4: Sub BleTagBattery_readSensorValue (BLETAG_BATTERY) - processing gatttool response: 64
2017.03.03 01:03:48 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - processing gatttool response for device GTAG_ABC. batteryLevel: 100
2017.03.03 01:03:48 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device found. device: GTAG_XYZ
2017.03.03 01:03:48 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device name: Gigaset G-tag
2017.03.03 01:03:48 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - device address: AA:BB:CC:DD:EE:FF
2017.03.03 01:03:53 4: Sub BleTagBattery_readSensorValue (BLETAG_BATTERY) - call gatttool char read loop: 0, result: Characteristic value/descriptor: 5e

2017.03.03 01:03:53 4: Sub BleTagBattery_readSensorValue (BLETAG_BATTERY) - processing gatttool response: 5e
2017.03.03 01:03:53 4: Sub BleTagBattery_BlockingRun (BLETAG_BATTERY) - processing gatttool response for device GTAG_XYZ. batteryLevel: 94
2017.03.03 01:03:53 4: Sub BleTagBattery_BlockingDone (BLETAG_BATTERY) - set readings batteryLevel and battery of device: GTAG_ABC
2017.03.03 01:03:53 4: Sub BleTagBattery_BlockingDone (BLETAG_BATTERY) - set readings batteryLevel and battery of device: GTAG_XYZ
2017.03.03 01:03:53 4: Sub BleTagBattery_BlockingDone (BLETAG_BATTERY) - done


Vielleicht hilft dir auch das hier weiter: http://stackoverflow.com/questions/32947807/cannot-connect-to-ble-device-on-raspberry-pi
Ich habe die hier erwähnten 3 Einträge in meiner main.conf drin stehen, da ich auch am Anfang mal ähnliche Probleme hatte.

mumpitzstuff

Zitat von: Mumpitz am 02 März 2017, 22:27:45
Müssen vorgängig die alten Scripte deaktiviert oder etwas deinstalliert werden?

Nein. Das sollte nicht notwendig sein. Beides sollte nebeneinander existieren können, falls du Skripte meinst die deinen Batteriestatus vorher ausgelesen haben. Wenn das Modul aber funktioniert, dann würde ich es machen, um dein System sauber zu halten.

Wenn du andere Skripte meinst, kommt es drauf an was es ist.

binford6000

ZitatWas hast du sonst noch auf deinem Bluetooth Dongle laufen? Zufällig lepresenced oder irgendwelche anderen Skripte die dauerhaft den Bluetooth Dongle blockieren z.b. mit: hcitool lescan?

Genau, nur lepresenced läuft zur Erkennung des gtags.

ZitatVielleicht hilft dir auch das hier weiter: http://stackoverflow.com/questions/32947807/cannot-connect-to-ble-device-on-raspberry-pi
Ich habe die hier erwähnten 3 Einträge in meiner main.conf drin stehen, da ich auch am Anfang mal ähnliche Probleme hatte.

Das habe ich auch gefunden und es hat funktioniert da ich zwischenzeitlich Probleme mit dem gtag hatte.
Auf einem zweiten rpi 1 mit dem selben BT Dongle funktionierte das Ganze...

VG Sebastian

mumpitzstuff

lepresenced und irgend etwas anderes das Gatttool verwendet ist eigentlich der worst case. Das liegt auch nicht an dem Modul von mir, sondern das ist generell so. Das ist vergleichbar damit, das sich zwei um einen Lolli streiten, aber es ist nur einer da. Beide versuchen sich den Lolli immer gegenseitig weg zu nehmen (in diesem Fall: Lolli = dein Bluetooth Dongle). Man kann dann lediglich folgendes mal versuchen (ohne Erfolgsgarantie), damit andere Module den Lolli länger als 1s von lepresenced klauen können:

1.) lepresenced beenden
2.) das lepresenced skript mit einem Editor aufmachen und den Wert "constant RETRY_SLEEP" anstatt auf 1 auf einen höheren Wert zu setzen (ich würde mal mit 20 starten und gucken obs dann geht und schrittweise runtergehen bis es nicht mehr geht)
3.) speichern und deamon neu starten

Das sorgt dann dafür das lepresenced in der Funktion bluetooth_scan_thread() einen Fehler feststellt, da sich Gatttool den Lolli geklaut hat, dann aber z.B. 20s wartet, bevor es versucht sich den Lolli zurück zu holen... Es führt aber auch dazu, dass lepresenced in dieser Zeit von z.B. 20s keinen aktuellen Status z.B. deiner Tags liefern kann!

Wenn das auch zu nichts führt, hilft nur ein zweiter Bluetooth Dongle oder weitere Änderungen am lepresenced Deamon. In weiter unten liegenden Schichten von Bluez kann man wahrscheinlich auch den parallelen Betrieb eines Scanns und des Auslesens von Werten abbilden, das erfordert aber ein komplett neues Framework. Soweit ich informiert bin, wird an einem solchen Framework bereits gearbeitet, die Zeitschiene ist jedoch unbekannt.

PS: Um überhaupt mal zu prüfen, ob das Modul funktioniert, kannst du lepresenced ja auch mal beenden und dann gucken was passiert. Dann müsste in jedem Fall der Batterielevel ausgelesen werden. Nach dem Abschießen von lepresenced muss man manchmal auch den Bluetooth Dongle resetten oder abzeihen/dranstecken, weil das Interface abgestürzt ist...

binford6000

Hallo,
Zitatdas lepresenced skript mit einem Editor aufmachen und den Wert "constant RETRY_SLEEP" anstatt auf 1 auf einen höheren Wert zu setzen (ich würde mal mit 20 starten und gucken obs dann geht und schrittweise runtergehen bis es nicht mehr geht)

Das wäre ja ein gangbarer Weg. Das PRESENCE-Device schaut auch nur alle 60s ob der gtag da ist. Werde ich auf jeden Fall mal testen!

ZitatPS: Um überhaupt mal zu prüfen, ob das Modul funktioniert, kannst du lepresenced ja auch mal beenden und dann gucken was passiert. Dann müsste in jedem Fall der Batterielevel ausgelesen werden. Nach dem Abschießen von lepresenced muss man manchmal auch den Bluetooth Dongle resetten oder abzeihen/dranstecken, weil das Interface abgestürzt ist...

Das würde mir im Endeffekt sogar auch genügen. Einmal die Woche sogar nur. Mein gtag ist jetzt anderthalb Jahre im Einsatz und noch keine Batterie tauschen müssen. Vielleicht kann ich das alles in ein kleines Script packen und per cronjob wöchentlich ausführen lassen...

Erstmal Danke für die Hilfestellung!
VG Sebastian

micky0867

Hallo,

das unterschiedliche Handling wegen uuid und handle sollte überflüssig sein.
Die entsprechende UUID muss für GATT kompatible Geräte immer 0x2A19 sein, dafür gibt es eine Spezifikation:
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.battery_level.xml

Diese UUID funktioniert bei mir sowohl mit GTags, als auch mit NUTs und übrigens auch mit meinem Herzfrequenzsensor von BerryKing.

Der Unterschied bei den beiden Tags ist nur das mit dem public/random.
Die NUTs benötigen im Aufruf das "-t random", sonst geht es nicht.
Die GTags hingegen brauchen "-t public", oder gar nichts, was intern aber einem public gleich kommt.

Micky

mumpitzstuff

Das ist eine super Information. Ich habe da nicht weiter nachgeforscht, sondern lediglich die Quellen im Internet angeschaut und dort war es überall so drin. Dachte das Gigaset hier ein extra Würstchen kocht. Was auch nicht sonderlich verwunderlich gewesen wäre, denn das machen leider viele Hersteller. Ich werde das mal probieren und dann den Code etwas entschlacken wenn es passt.
Im aktuellen devel Branch findet man bereits eine Version, in der probiert wird ob der Tag auf random oder public reagiert und diese Einstellung wird dann gespeichert und beim nächsten Mal erneut verwendet (dann muss nicht probiert werden). Damit sollte das Ding dann relativ kompatibel sein.

Thema lepresenced: Ich hab mir das bei mir noch mal angesehen und das hciDevice so eingestellt, dass das Modul auf dem Dongle läuft, auf dem auch lepresenced läuft. Ich bekomme dann sehr sporadisch die Batterieinformationen vom ersten Tag, für den zweiten reicht die Zeit nicht mehr (default bei lepresenced ist 1s) und das Auslesen schlägt fehl. Ich denke deshalb, dass die Erhöhung von RETRY_SLEEP das Problem an dieser Stelle weitestgehend beheben wird. Je mehr Tags man auslesen möchte, desto höher muss man wahrscheinlich den Wert wählen, um genug Zeit zu haben. Da das nur alle 6h kurz passiert, sollte das aber zu verschmerzen sein. Ich schreib das dann auch so noch mal ins readme rein, vielleicht hilfts dem einen oder anderen.