web-dev-qa-db-ja.com

python)でBluetooth LowEnergyを見つける

このコードを変更してBluetoothLow Energyデバイスも含めることはできますか? https://code.google.com/p/pybluez/source/browse/trunk/examples/advanced/inquiry-with-rssi.py?r=1

電話やその他のBluetooth4.0デバイスなどのデバイスは見つかりますが、BLEは見つかりません。これを変更できない場合、hcitool lescanを実行して、Python内のhciダンプからデータをプルすることは可能ですか?ツールを使用して、探しているデバイスを確認できます。これにより、hcidumpでRSSIが提供されます。これが、私の最終目標です。 BLEデバイスからMACアドレスとRSSIを取得します。

ありがとう!

7
user3582887

コメントで述べたように、そのライブラリはBLEでは機能しません。

簡単なBLEスキャンを実行するためのサンプルコードを次に示します。

_import sys
import os
import struct
from ctypes import (CDLL, get_errno)
from ctypes.util import find_library
from socket import (
    socket,
    AF_BLUETOOTH,
    SOCK_RAW,
    BTPROTO_HCI,
    SOL_HCI,
    HCI_FILTER,
)

if not os.geteuid() == 0:
    sys.exit("script only works as root")

btlib = find_library("bluetooth")
if not btlib:
    raise Exception(
        "Can't find required bluetooth libraries"
        " (need to install bluez)"
    )
bluez = CDLL(btlib, use_errno=True)

dev_id = bluez.hci_get_route(None)

sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)
sock.bind((dev_id,))

err = bluez.hci_le_set_scan_parameters(sock.fileno(), 0, 0x10, 0x10, 0, 0, 1000);
if err < 0:
    raise Exception("Set scan parameters failed")
    # occurs when scanning is still enabled from previous call

# allows LE advertising events
hci_filter = struct.pack(
    "<IQH", 
    0x00000010, 
    0x4000000000000000, 
    0
)
sock.setsockopt(SOL_HCI, HCI_FILTER, hci_filter)

err = bluez.hci_le_set_scan_enable(
    sock.fileno(),
    1,  # 1 - turn on;  0 - turn off
    0, # 0-filtering disabled, 1-filter out duplicates
    1000  # timeout
)
if err < 0:
    errnum = get_errno()
    raise Exception("{} {}".format(
        errno.errorcode[errnum],
        os.strerror(errnum)
    ))

while True:
    data = sock.recv(1024)
    # print bluetooth address from LE Advert. packet
    print(':'.join("{0:02x}".format(x) for x in data[12:6:-1]))
_

Bluezに付属しているhcitoolgatttoolのソースコードを見て、それらすべてをつなぎ合わせる必要がありました。コードは_libbluetooth-dev_に完全に依存しているため、最初にインストールされていることを確認する必要があります。

より良い方法は、dbusを使用してbluetoothdを呼び出すことですが、私はまだそれを調査する機会がありませんでした。また、dbusインターフェースは、BLE接続を確立した後にBLE接続で実行できる機能に制限があります。

編集:

MartinTramšakは、Python 2では、最後の行をprint(':'.join("{0:02x}".format(ord(x)) for x in data[12:6:-1]))に変更する必要があると指摘しました。

24
Tim Tisdall

pygattlib を試すこともできます。デバイスの検出に使用でき、(現在)読み取り/書き込み特性の基本的なサポートがあります。現在RSSIはありません。

次のスニペットを使用して発見できます。

from gattlib import DiscoveryService

service = DiscoveryService("hci0")
devices = service.discover(2)

DiscoveryServiceはデバイスの名前を受け入れ、メソッドdiscoverは待機中の応答のタイムアウト(秒単位)を受け入れます。 devicesは辞書であり、BLアドレスをキーとして、名前を値として使用します。

pygattlib はDebian(またはUbuntu)用にパッケージ化されており、ダウンロードセクションには.debがあります。

4
oscarah