citruz / beacontools Goto Github PK
View Code? Open in Web Editor NEWA Python beacon scanning library.
License: MIT License
A Python beacon scanning library.
License: MIT License
Hello
thank you a lot for this great code
You are a life saver!
However, I need some help regarding the scanning algorithm
how can I edit the scanning so that I only hear from one specific mac address
I do not want to scan for all BLE packets in air, I just need to lock the scanning to one mac address
Please help me
Thank you
Jesy
The program works almost perfectly on the Raspberry Pi, but the exact same program does not return any thing (even the devices the Raspberry Pi detects) on my Lenovo Thinkpad X1 Carbon (running Debian Buster). sudo hcitools lescan returns "Set scan parameters failed: Input/output error". Nothing I do from the countless online suggestions seems to make that error go away. I've restarted hci0, restarted my machine, restarted bluetooth services, etc and the error still persists. bluetoothctl however can scan and detect the le iBeacon messages. Can someone help me figure this out?
Hi,
I just try use it with Python3.5 in RaspberryPI3B+, but error occurred.
please let me know what i am missing.
Import error: No module named "construct"
Hi,
I'm facing a problem with Bluez library when running Raspberry Pi OS on a Raspberry Pi Zero W.
I'm running the latest image version with release date in March 4th 2021.
I used the example on the pypi.org page, as shown below.
import time
from beacontools import BeaconScanner, IBeaconFilter
def callback(bt_addr, rssi, packet, additional_info):
print("<%s, %d> %s %s" % (bt_addr, rssi, packet, additional_info))
# scan for all iBeacon advertisements from beacons with the specified uuid
scanner = BeaconScanner(callback,
device_filter=IBeaconFilter(uuid="e5b9e3a6-27e2-4c36-a257-7698da5fc140")
)
scanner.start()
time.sleep(5)
scanner.stop()
# scan for all iBeacon advertisements regardless from which beacon
scanner = BeaconScanner(callback,
packet_filter=IBeaconAdvertisement
)
scanner.start()
time.sleep(5)
scanner.stop()
I get always the same error, as described below.
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/home/pi/.local/lib/python3.7/site-packages/beacontools/scanner.py", line 144, in run
self.socket = self.backend.open_dev(self.bt_device_id)
File "/home/pi/.local/lib/python3.7/site-packages/beacontools/backend/linux.py", line 13, in open_dev
socket.setsockopt(bluez.SOL_HCI, bluez.HCI_FILTER, filtr)
_bluetooth.error: (9, 'Bad file descriptor')
jaap@custard:~$ sudo apt-get install libbluetooth-dev libcap2-bin\
[sudo] password for jaap:
Reading package lists... Done
Building dependency tree
Reading state information... Done
libbluetooth-dev is already the newest version.
libcap2-bin is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
jaap@custard:$ sudo setcap 'cap_net_raw,cap_net_admin+eip' $ pip install beacontools[scan]
jaap@custard:
Downloading/unpacking beacontools[scan]
Downloading beacontools-1.1.0-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): construct==2.8.12 in /usr/local/lib/python2.7/dist-packages (from beacontools[scan])
Downloading/unpacking PyBluez==0.22 (from beacontools[scan])
Downloading PyBluez-0.22.zip (109kB): 109kB downloaded
Running setup.py (path:/tmp/pip-build-c3w9ob/PyBluez/setup.py) egg_info for package PyBluez
warning: no files found matching '*.h' under directory 'osx'
warning: no previously-included files matching '*.pyc' found under directory '*'
warning: no previously-included files matching '*.o' found under directory '*'
warning: no previously-included files matching '*.opp' found under directory '*'
Installing collected packages: beacontools, PyBluez
Running setup.py install for PyBluez
building 'bluetooth._bluetooth' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I./port3 -I/usr/include/python2.7 -c bluez/btmodule.c -o build/temp.linux-x86_64-2.7/bluez/btmodule.o
In file included from bluez/btmodule.c:20:0:
bluez/btmodule.h:4:20: fatal error: Python.h: No such file or directory
#include "Python.h"
^
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
Complete output from command /usr/bin/python -c "import setuptools, tokenize;file='/tmp/pip-build-c3w9ob/PyBluez/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /tmp/pip-oKbi5u-record/install-record.txt --single-version-externally-managed --compile:
running install
running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/btcommon.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/msbt.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/widcomm.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/init.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/ble.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/osx.py -> build/lib.linux-x86_64-2.7/bluetooth
copying bluetooth/bluez.py -> build/lib.linux-x86_64-2.7/bluetooth
running build_ext
building 'bluetooth._bluetooth' extension
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/bluez
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I./port3 -I/usr/include/python2.7 -c bluez/btmodule.c -o build/temp.linux-x86_64-2.7/bluez/btmodule.o
In file included from bluez/btmodule.c:20:0:
bluez/btmodule.h:4:20: fatal error: Python.h: No such file or directory
#include "Python.h"
^
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
Cleaning up...
Command /usr/bin/python -c "import setuptools, tokenize;file='/tmp/pip-build-c3w9ob/PyBluez/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /tmp/pip-oKbi5u-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip-build-c3w9ob/PyBluez
Storing debug log for failure in /home/jaap/.pip/pip.log
jaap@custard:~$
Hi,
Can your library be used to determine the approximate distance from the beacon?
Regards
Krzysiek
It would be nice if beacontools would support a recent version of construct.
home-assistant/supervisor#356
home-assistant/core#12298 (comment)
On my laptop I have manjaro linux and bluetooth dongle 4.0. Example script for scannig ibeacons shows nothing (no beacons, no errors) but hcitool shows my beacon. Why?
I got wrong temperature when the temperature is negative and also seconds_since_boot also has an extra 0 (multiplied by 10)
from beacontools import parse_packet
import codecs
data = '0201060303aafe1116aafe20000c8df000001755d10885a5b8'
tlm_frame = parse_packet(codecs.decode(data, 'hex'))
print(tlm_frame.temperature) # gives 240 for -15C
print(tlm_frame.seconds_since_boot) # gives 142976440(1650 days) instead of 14297644 (165 days)
voltage is correct!
nrfConnect can correctly read these values. https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=en_CA&gl=US
First: I know this is a permissions issue - and I also see the step in the setup instructions to mitigate it.
Ubuntu 17.10 x64
Pycharm 2018.1.3 (developing here)
Python 3.6 in a virtualenv
pip install beacontools
# install libbluetooth headers and libpcap2
sudo apt-get install python-dev libbluetooth-dev libcap2-bin
# grant the python executable permission to access raw socket data
sudo setcap 'cap_net_raw,cap_net_admin+eip' $(readlink -f $(which python))
# install beacontools with scanning support
pip install beacontools[scan]
Then copy-paste example code from Scanner subsection (scanner = BeaconScanner...
)
Exception in thread Thread-5:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/home/william/PycharmProjects/bt-beacon/venv/lib/python3.6/site-packages/beacontools/scanner.py", line 94, in run
self.toggle_scan(True)
File "/home/william/PycharmProjects/bt-beacon/venv/lib/python3.6/site-packages/beacontools/scanner.py", line 110, in toggle_scan
self.bluez.hci_send_cmd(self.socket, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, command)
_bluetooth.error: (1, 'Operation not permitted')
Various forms of sudo setcap...
including sudo setcap 'cap_net_raw,cap_net_admin+eip' $(which hcitool)'
.
Has anyone else experienced and solved this issue?
Is it possible to pass different technologies filters? Eg. [EddystoneFilter(x), iBeaconFilter(y), ...]
Hi, i have 2 BT devices (one integrated in a old MacBook Pro not BLE and one USB dongle supporting BLE).
I need to choose the USB Dongle to listen Estimote Beacons...how i can set the scanner example to use hci1 and not hc0???
thanks Luca
First, I want to apologize for posting this here, but I could not find any good resources for BLE issues on bluez 5.5, Raspian etc.
I made the app work with a "hack" in the code in scanner.py and changed
self.hci_version = self.get_hci_version()
to self.hci_version = 8 #self.get_hci_version()
, thus tricking the code into believing I am running bluetooth version 4.8.
If I reverse it to the original (correct) version, I get in btmon the following errors
> HCI Event: Command Complete (0x0e) plen 4
LE Set Extended Scan Parameters (0x08|0x0041) ncmd 1
Status: Unknown HCI Command (0x01)
....
> HCI Event: Command Complete (0x0e) plen 4
LE Set Extended Scan Enable (0x08|0x0042) ncmd 1
Status: Unknown HCI Command (0x01)
....
Question: Do I need to enable something special to make the extended commands work, start bluetoothd with a special option?
hardware: Raspberry PI 4B, supposedly BT 5 enabled. Kernel 5.10.11-v7l+, Python 3.7.3
edit: my result for hciconfig -a:
hci0: Type: Primary Bus: UART
BD Address: DC:A6:32:F4:13:4F ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING PSCAN
RX bytes:668819 acl:793 sco:0 events:66903 errors:0
TX bytes:104635086 acl:122991 sco:0 commands:901 errors:0
Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH SNIFF
Link mode: SLAVE ACCEPT
Name: 'rpi4b'
Class: 0x0c0000
Service Classes: Rendering, Capturing
Device Class: Miscellaneous,
HCI Version: 5.0 (0x9) Revision: 0x156
LMP Version: 5.0 (0x9) Subversion: 0x6119
Manufacturer: Cypress Semiconductor Corporation (305)
Hello and thanks for your work
I am trying to build a Python scripts to collect Temp and Humidity from some beacons.
I downloaded your code to a Raspberry pi 4 and I do not receive any information. Should this could work on a RPI4?
When I use bluetoothctl I see two devices. Below is a sample of what I see.
[CHG] Device DD:34:02:06:D0:60 ServiceData Key: 0000feaa-0000-1000-8000-00805f9b34fb
[CHG] Device DD:34:02:06:D0:60 ServiceData Value:
21 01 0f 0e 07 1a 5f 1f 7e 00 11 ff fc 04 06 !....._.~......
[CHG] Device DD:34:02:06:D0:60 ServiceData Key: 00002080-0000-1000-8000-00805f9b34fb
[CHG] Device DD:34:02:06:D0:60 ServiceData Value:
6d 01 00 00 00 00 m.....
[CHG] Device D0:AA:E6:17:56:99 ServiceData Key: 00000318-0000-1000-8000-00805f9b34fb
[CHG] Device D0:AA:E6:17:56:99 ServiceData Value:
24 2b 15 2f 00 00 00 00 00 00 00 00 00 00 00 00 $+./............
[CHG] Device D0:AA:E6:17:56:99 ServiceData Key: 00001803-0000-1000-8000-00805f9b34fb
[CHG] Device D0:AA:E6:17:56:99 ServiceData Value:
d0 aa e6 17 56 99 00 01 00 02 06 03 e8 64 ....V........d
Thanks in advance for your help.
Hello,
Sorry to bother you but I'm trying to read a decimal temperature from a Minew eddyston beacon.
I have the constructor documentation but I don't understand how to modify your code to read correctly the temperature. My question is probably basic but my knowledges are also very limited
Below is the data format, may I ask you if you have a few time to take a look and give me some hints on how to be able to read the temperature and maybe the humidity.
Thanks a lot anyway for your beacontools is great
I've edited scanner.py to serve my purposes by creating the _mon in the start, and deleting it in the stop. Not sure if this is a good way to handle it as I don't understand python as well as you do.
I wanted to check the same beacon on a 5 second interval and produce a log of the RSSI values.
But with your code I was trying to start a thread again which yielded an error message.
This is the code change that I made starting at line 51 of scanner.py
self.callback=callback
self.bt_device_id=bt_device_id
self.device_filter=device_filter
self.packet_filter=packet_filter
def start(self):
"""Start beacon scanning."""
self._mon = Monitor(self.callback, self.bt_device_id, self.device_filter, self.packet_filter)
self._mon.start()
def stop(self):
"""Stop beacon scanning."""
self._mon.terminate()
del(self._mon)
Maybe you have already created a way for me to do what I want, or maybe this is a better approach since the thread is destroyed and recreated on start/stop.
Hi,
I use beacontools for the Eddystone TLM protocol. During a test with an Estimote-Beacon I noticed the following output:
That's my code to scan the beacons:
import time
from beacontools import BeaconScanner, EddystoneTLMFrame, EddystoneFilter, EddystoneUIDFrame, parse_packet
def callback(bt_addr, rssi, packet, additional_info):
print(packet)
# scan for all TLM frames of beacons
scanner = BeaconScanner(callback,
device_filter=EddystoneFilter(namespace="edd1ebeac04e5defa123"),
packet_filter=[EddystoneTLMFrame]
)
scanner.start()
time.sleep(10)
scanner.stop()
And this is the output:
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855911, seconds since boot: 430306518>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 49174 Celsius, advertising count: 14855912, seconds since boot: 430306521>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855913, seconds since boot: 430306524>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855915, seconds since boot: 430306530>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855916, seconds since boot: 430306533>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 23 Celsius, advertising count: 14855918, seconds since boot: 430306539>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855920, seconds since boot: 430306545>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855921, seconds since boot: 430306549>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855922, seconds since boot: 430306552>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855925, seconds since boot: 430306561>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 49174 Celsius, advertising count: 14855928, seconds since boot: 430306570>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855929, seconds since boot: 430306573>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855930, seconds since boot: 430306576>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855931, seconds since boot: 430306579>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855932, seconds since boot: 430306582>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855933, seconds since boot: 430306585>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 49174 Celsius, advertising count: 14855934, seconds since boot: 430306588>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 49174 Celsius, advertising count: 14855935, seconds since boot: 430306592>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 49174 Celsius, advertising count: 14855936, seconds since boot: 430306595>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855937, seconds since boot: 430306598>
EddystoneTLMFrame<voltage: 2956 mV, temperature: 32790 Celsius, advertising count: 14855938, seconds since boot: 430306601>
What's the value of temperature? It varies very much and once I have got my room temperature of 23 degrees.
Thank you for your help!
Please make RFU fields of Eddystone UID frame optional or print a warning when a UID frame is received missing RFU field. Today it is just discarded and took me some time to figure out why.
On top of that it also seems like temperature is not reported correct. It seems it cannot parse the fixed-point artithmetic of the frame. xx.xx. Maybe the beacons tested just reported even degrees, hence it was reported little endian? My beacon reports with decimal value...like 23.21
Iยดm testing with Bluvision Beeks Beacons
Thank you
how to change scanner speed? i use raspberry pi 4 model B and HM17
hm17 send signal set up 300ms but scanner couldnt how can i fix it?
Hello,
I am trying to parse the BLE Gateway data send to cloud. The data is getting send in text format,which I am unable to parse using parse_packet() function.
Data send is '0201061AFF4C000215E2C56DB5DFFB48D2B060D0F5A71096E027100000D7' .
Any help is very much appreciated.
Thanks And Regards,
Rupak Banerjee.
Hi
Since i want to connect a Cypress CYALKIT-E2 device to a raspberry pi 3, and since Python, Bluetooth and others are configured already, how can i make everything you've done work ?
I know i can find my device's MAC address easily, how can i connect my RP3 to the device AND use your program to store data in a .whatever file ?
What could be the step by step solution ?
Thanks in advance.
Ben
It is possible to check on beacon battery charge level?
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/home/jslay/.local/lib/python3.8/site-packages/beacontools/scanner.py", line 153, in run
subevent = to_int(pkt[3])
IndexError: index out of range
Hi, we are about to develop a device wherein we will be using the eddystone beacon as our protocol. And it seems to be that the format of the packets are standard to any existing app. But what we did was we customized the format of the packets to add more sensor data (heart rate and spo2)
Now the problem was, when I used this library as sentry, I can't seem to find any filter packet filter that will enable me to display the tlm frames as raw packets.
Will it be possible to display the tlm frames as raw packets using this library?
Thank you,
Jonathan
Hello everyone,
I trying to use to example file for scanning EddystoneUID frames... but it looks like it doesn't work. I know that there are similar related closed issues for the same problem (#10 and #25) and @citruz has replied that this has been fixed in 1.3.0 but it does not seems to be the case (at least for me).
I removed only one line form the original example, the one that is used to filter the namespace.
device_filter=EddystoneFilter(namespace="12345678901234678901"),
So here is the code i used :
import time
from beacontools import BeaconScanner, EddystoneTLMFrame, EddystoneFilter, EddystoneUIDFrame
def callback(bt_addr, rssi, packet, additional_info):
print("<%s, %d> %s %s" % (bt_addr, rssi, packet, additional_info))
# scan for all TLM frames of beacons
scanner = BeaconScanner(callback,
packet_filter=[EddystoneTLMFrame, EddystoneUIDFrame]
)
scanner.start()
time.sleep(10)
scanner.stop()
The console is not printing anything, i have several physical EddystoneUID beacons and also some that are emulated with the "Beacon Simulator" android app.
Can somebody please tell me what i am doing wrong ?
Thanks a lot.
Dear all,
Is it possible to grab the UUID of beacons during scanning, save it as a variable, and use it in the python programme? Where do I return the UUID and where do I save it to? This is because I can only see scanner.start()
Are there other functionalities out there or ways that I can grab the UUID,Major,Minor and RSSI values for further use?
Many thanks for your help in advance,
Clement 14
I use the beacontools for my project, "CoronaTeller" (dutch for Corona counter)
Testing :
$ bluetoothctl
[bluetoothctl]scan.transport le
[bluetoothctl]scan.uuids 0xfd6f
[bluetoothctl]scan on
Gives all beacons including the Android phones. Running the beacontoools scan tool (without any packet filtering) gives only my iPhone, not an Android phone.
First a big thank you for this lib ๐
I'm writing an application, that has to match on an exact pair of Major and Minor ID and only call the callback if all of my filters do match.
I use the IBeaconFilter like this:
fltr = IBeaconFilter(major=0xff00, minor=0x0000)
, but then I receive all iBeacon advertisements for
beacons with the Major ID 0xff00 (minor is "ignored", 0x0 == False
).. When I try to use the following filter it works as expected (I only see packets of that exact iBeacon) fltr = IBeaconFilter(major=0xff00, minor=0x0001)
So the bug is in the device_filters.py IBeaconFilter initialization, because 0x0 == False
, so the following line is False
https://github.com/citruz/beacontools/blob/master/beacontools/device_filters.py#L36
so I'd refactor the code like this:
class IBeaconFilter(DeviceFilter):
"""Filter for iBeacon."""
def __init__(self, uuid=None, major=None, minor=None):
"""Initialize filter."""
super(IBeaconFilter, self).__init__()
if uuid is None and major is None and minor is None:
raise ValueError("IBeaconFilter needs at least one argument set")
if uuid is not None:
self.properties['uuid'] = uuid
if major is not None:
self.properties['major'] = major
if minor is not None:
self.properties['minor'] = minor
This is kind of ugly, but should work correctly :)
Hello,
I tested with iBeacon Minew D15N Keychain Beacon and everything is working fine so far. Still need to tune interval_ms, window_ms + the interval&power of beacon for more reliable results.
Is it possible to add battery info? The beacon is broadcasting this.
Regards,
Viorel
I tried the scanner examples for iBeacons and Eddystone Beacons on a Raspberry PI Zero W and they work fine. When doing the same on a Raspberry 4B the examples work in the sense that no errors are thrown, but they fail in finding any Beacons.
OS is Raspbian Buster
beacontools[scan] is 2.1.0
bluez is 5.50
Python 3.7.3
Any advice how to debug this?
I had this library set up and running nicely on raspberry pi 3b+ on raspbian stretch, I recently installed "Raspberry Pi OS" and I cant seem to find any BT packets when scanning now. Is there something different that should be done for allowing BT read permissions to python in Raspberry Pi OS?
Is there a way to get raw data scanned beacon that can be used to know battery status of the beacon?
Hello All,
I've installed beacontools on fresh new RaspberryPi image.
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
sudo apt-get install python3-pip
pip3 install beacontools
pip3 list | grep -i beacontools
says: beacontools 2.1.0
however I run python3, saying import beacontools
and get error:
ModuleNotFoundError: No module named 'beacontools'
what can be wrong?
It looks like there is a signed vs unsigned issue? I have a beacon inside a cooler with dry ice. The temperature inside is about -36 degrees C. My script is reporting 220 degrees C. If you interpret this number as a two's complement you get the right answer. Here is what is reported:
<ac:23:3f:2a:e0:4e, -49> EddystoneTLMFrame<voltage: 3216 mV, temperature: 220 Celsius, advertising count: 12513900, seconds since boot: 99146930>
Here is my code:
import time
from beacontools import BeaconScanner, IBeaconFilter
def callback(bt_addr, rssi, packet, additional_info):
str = "<%s, %d> %s %s" % (bt_addr, rssi, packet, time.time())
print(str)
scanner = BeaconScanner(callback)
scanner.start()
time.sleep(4)
scanner.stop()
in structs/ibeacon.py:
"flags" / Const(b"\x02\x01\06")
Is too strict, some devices emit \x02\x01\04, notably cypress ones
I'm trying to understand if it is possible using this library to get (besides the information already there) the name of the bluetooth beacon.
I checked the code and didn't see any place where the information might be loaded. But I rather ask and be sure.
Hi,
I juste wanted to know if it is possible to pass an array of namespaces to the EddystoneFilter function so that we can filter multiple possible namespaces.
Thank you.
Hi there,
First, thank you for this great library.
I use your library in one of my programs on raspberry pi devices to scan for surrounding iBeacon beacons and report their information. It works perfectly on raspberry pi3 B. However, when I run the scanner_ibeacon_example.py example on raspberry pi 3 B plus model device, it doesn't return any beacons information.
Interestingly scanner_ibeacon_example.py works and discovers the around beacons after I scan first using bluetoothctl or hcitool utilities.
Thank You
Hello
The test computer is Pericision 5530 of DELL and OS is Ubuntu 18.04.
It is not input packets before executing 'scan on' with bluetoothctl program.
Added the debug code as follow in scanner.py.
while self.keep_going:
pkt = self.socket.recv(255)
hexdump.hexdump(pkt)
It shows packets after scan on:
00000000: 04 0E 04 01 05 20 00 ..... .
00000000: 04 0E 04 01 41 20 00 ....A .
00000000: 04 0E 04 02 42 20 00 ....B .
00000000: 04 0F 04 00 02 01 04 .......
00000000: 04 3E 39 0D 01 10 00 01 33 70 BD FA C5 31 01 00 .>9.....3p...1..
00000010: FF 00 BE 00 00 00 00 00 00 00 00 00 1F 1E FF 06 ................
00000020: 00 01 09 20 02 B4 C7 9E AF A2 CB 8E EF D6 F8 FA ... ............
00000030: 1C EC 64 23 6F 6E C7 50 6B 9B 86 54 ..d#on.Pk..T
00000000: 04 3E 39 0D 01 10 00 01 FC 2B CA 07 71 32 01 00 .>9......+..q2..
00000010: FF 00 C0 00 00 00 00 00 00 00 00 00 1F 1E FF 06 ................
00000020: 00 01 09 20 02 8B C2 F1 D7 57 9D 5B 90 34 4A 87 ... .....W.[.4J.
00000030: C5 C4 BD 64 F1 8D 06 39 BA F7 28 AB ...d...9..(.
00000000: 04 3E 31 0D 01 13 00 01 05 DD 32 2E E7 50 01 00 .>1.......2..P..
00000010: FF 00 B5 00 00 00 00 00 00 00 00 00 17 02 01 06 ................
00000020: 13 FF 4C 00 0C 0E 00 89 31 FF 2F 5A 09 10 F7 8E ..L.....1./Z....
00000030: 3F 69 AB 04 ?i..
How can I operation without running 'scan on' command of bluetoothctl ?
Please give me a advice.
Can you give me an idea, how to take the average of RSSI values obtained while scanning Ibeacon or edd
Thanks :)
I've been going through the example
https://github.com/citruz/beacontools/blob/master/examples/scanner_eddystone_example.py
My question is does scanner.start() on line 24 start a scanning process in the background, which continues running and calling the callback, while the main code waits for 10 seconds due to time.sleep(10)
?
Thanks,
Nachiket
I am working on the ibeacon scanning on my Raspberry Pi 4B (Python 2.7.16, bluez 5.50, Raspbian GNU/Linux 10), though it displays a error message:
from bluetooth import _bluetooth as bluez ModuleNotFoundError: No module named 'bluetooth'
I tried installing the Bluetooth module via python3 -m pip install bluetooth, but another error message is shown:
Could not install packages due to an EnvlironmentError: 404 Client Error: Not Found for url: https://pypi.org/simple/bluetooth
Please help.
Hey I try to use this on my arch linux box, but somehow I can't make it work. I try to run:
import time
from beacontools import (BeaconScanner, EddystoneTLMFrame, EddystoneFilter,
IBeaconFilter)
def callback(bt_addr, rssi, packet, additional_info):
print("<%s, %d> %s %s" % (bt_addr, rssi, packet, additional_info))
# scan for all iBeacon advertisements from beacons with the specified uuid
scanner = BeaconScanner(callback,
#device_filter=IBeaconFilter(uuid="e5b9e3a6-27e2-4c36-a257-7698da5fc140")
)
scanner.start()
But this never finds any package at all. So I started looking into details of the library itself. The first problem was:
beacontools/beacontools/scanner.py
Lines 168 to 172 in 15a83e9
Up to now I have never seen a package passing this check. All I receive fails this check, however I'm at a science conference and there is a crazy amount of beacons around me. I also use the Android Beacon Simulator and stetted up an IBeacon.
As a matter of desperation I removed the check and went on. However maybe not surprisingly,
beacontools/beacontools/scanner.py
Line 177 in 15a83e9
Can this be a problem with the Bluetooth stack itself? Like wrong bluez version or so?
Please let me know what i am missing. I used exact example code mentioned.
Traceback (most recent call last):
File "BluetoothSept012020.py", line 4, in
from beacontools import BeaconScanner, EddystoneTLMFrame, EddystoneFilter#, EddystoneUIDFrame, EddystoneURLFrame
File "/home/pi/.local/lib/python2.7/site-packages/beacontools/init.py", line 3, in
from .scanner import BeaconScanner
File "/home/pi/.local/lib/python2.7/site-packages/beacontools/scanner.py", line 17, in
from .device_filters import BtAddrFilter, DeviceFilter
File "/home/pi/.local/lib/python2.7/site-packages/beacontools/device_filters.py", line 110
raise ValueError("bt_addr({}) wasn't a string".format(bt_addr)) from exc
^
SyntaxError: invalid syntax
Background: I implemented a class Node(threading.Thread)
that uses a GPS-monitoring thread and the Monitor
class to scan for BLE beacons. Like Monitor
, my GPS service also subclasses threading.Thread
.
When I run my Node
class thusly, all works well and I return to the Python prompt as the threads run:
gps_device = '/dev/ttyACA0'
node = Node(gps_device)
node.start()
Issue: When I run the same commands from the terminal (python node.py
) the Monitor
thread blocks at pkt = self.socket.recv(255)
which is from scanner.py
, line 97. A Ctrl-C
(aka KeyboardInterrupt
) allows the script to continue, albeit without BLE scanning.
Interestingly, I can after I interrupt the script that the Monitor
has been receiving and processing BLE packets. I printed the packets to console for debug, and they all come spilling out after the Ctrl-C
. Again, in the Python interpreter directly they are all printed real time.
Can you provide insight?
Code
# # # node.py
class Node(threading.Thread):
def __init__(self, gps_device):
threading.Thread.__init__(self)
self.daemon = False
logging.info("Setting up GPS service")
self.gps_svc = gps.CoordinateService(gps_device)
self.gps_svc.daemon = True
logging.info("Setting up BLE scanning service")
# TODO: This is blocking when run in terminal (aka how we do on Raspberry Pi)
self.scan_svc = scan.Monitor(self.on_receive, 0, None, None)
self.scan_svc.daemon = True
logging.info("Node initialized - ready for start")
def _on_receive(bt_addr, rssi, packet, properties):
# do stuff...
def run(self):
self.gps_svc.start()
self.scan_svc.start() # blocks here in terminal
while True:
# do stuff...
if __name__ == "__main__":
node = Node("/dev/ttyACM0")
node.start()
Hello,
I tryed out the Eddystone example code.
With this I got a few Problems.
When I put in the Namespace of my Beacons, their is 0 output.
When I put URLFrame into filter i got output.
When I put UIDFrame into filter i got 0 output.
So what could be the problem?
With best of wishes,
QuotenPole
I have been trying to run my rapberry Pi 3 with the beacontools library
but i keep getting the error
ConstructError("subcon[N] syntax can only be used for arrays use GreedyRange(subcon) instead?"
I am running it using pyhton2.7
Any idea how i can resolve this?
I have 4 Estimote beacons and I have enable Eddystone-UID, Eddystone-EID, Eddystone-URL, Eddystone-TLM broadcasting. They all share the same namespace, that I have used to filter the beacons as per your instruction. Unfortunately the script scanner_eddystone_example.py
doesn't return any result. No error is returned, the script just goes in timeout.
If I use instead the iBeacon protocol with the script scanner_ibeacon_example.py
I get all the beacons regularly filtered using their UUID, which is the same for them all.
I'm on a Raspberry Pi with Raspbian Lite and I have updated BlueZ from source to the version 5.50. Python is compiled with Bluetooth support. The command is executed with root privileges.
Hi,
I've been running it for over a month now and suddenly out of the blue, it has stopped working. The script executes but it is not reading any ibeacons. I double checked it with a mobile app too, the app is reading the beacons while the script is not.
While trying different solutions, I understood that the BLE scan itself is working perfectly fine i.e. if I try to scan for a BLE device from the command prompt using "bluetoothctl", it seems to be identifying the Ibeacons (I am assuming if this is working the BLE scanning functionality is working correctly on the laptop).
Any idea where the issue might be?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.