Python if语句没有';无法识别蓝牙信标

Python if语句没有';无法识别蓝牙信标,python,bluetooth,bluetooth-lowenergy,bluez,Python,Bluetooth,Bluetooth Lowenergy,Bluez,下面是BeaconScanner.py文件用于查找和列出ble信标的scanputility.py文件 #This is a working prototype. DO NOT USE IT IN LIVE PROJECTS import sys import struct import bluetooth._bluetooth as bluez OGF_LE_CTL=0x08 OCF_LE_SET_SCAN_ENABLE=0x000C def hci_enable_le_scan(so

下面是BeaconScanner.py文件用于查找和列出ble信标的scanputility.py文件

#This is a working prototype. DO NOT USE IT IN LIVE PROJECTS


import sys
import struct
import bluetooth._bluetooth as bluez

OGF_LE_CTL=0x08
OCF_LE_SET_SCAN_ENABLE=0x000C

def hci_enable_le_scan(sock):
    hci_toggle_le_scan(sock, 0x01)

def hci_disable_le_scan(sock):
    hci_toggle_le_scan(sock, 0x00)

def hci_toggle_le_scan(sock, enable):
    cmd_pkt = struct.pack("<BB", enable, 0x00)
    bluez.hci_send_cmd(sock, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, cmd_pkt)

def packetToString(packet):
    """
    Returns the string representation of a raw HCI packet.
    """
    if sys.version_info > (3, 0):
    return ''.join('%02x' % struct.unpack("B", bytes([x]))[0] for x in packet)
    else:
    return ''.join('%02x' % struct.unpack("B", x)[0] for x in packet)

def parse_events(sock, loop_count=100):
    old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
    flt = bluez.hci_filter_new()
    bluez.hci_filter_all_events(flt)
    bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
    sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
    results = []
    for i in range(0, loop_count):
    packet = sock.recv(255)
    ptype, event, plen = struct.unpack("BBB", packet[:3])
    packetOffset = 0
    dataString = packetToString(packet)
    """
    If the bluetooth device is an beacon then show the beacon.
    """
    #print (dataString)
    if dataString[34:50] == '0303aafe1516aafe' or '0303AAFE1116AAFE':
        """
        Selects parts of the bluetooth packets.
        """
        broadcastType = dataString[50:52]
        if broadcastType == '00' :
        type = "Eddystone UID"
        namespace = dataString[54:74].upper()
        instance = dataString[74:86].upper()
        resultsArray = [
        {"type": type, "namespace": namespace, "instance": instance}]
        return resultsArray

        elif broadcastType == '10':
        type = "Eddystone URL"
        urlprefix = dataString[54:56]
        if urlprefix == '00':
            prefix = 'http://www.'
        elif urlprefix == '01':
            prefix = 'https://www.'
        elif urlprefix == '02':
            prefix = 'http://'
        elif urlprefix == '03':
            prefix = 'https://'
        hexUrl = dataString[56:][:-2]
        url = prefix + hexUrl.decode("hex")
        rssi, = struct.unpack("b", packet[packetOffset -1])
        resultsArray = [{"type": type, "url": url}]
        return resultsArray

        elif broadcastType == '20':
        type = "Eddystone TLM"
        resultsArray = [{"type": type}]
        return resultsArray

        elif broadcastType == '30':
        type = "Eddystone EID"
        resultsArray = [{"type": type}]
        return resultsArray

        elif broadcastType == '40':
        type = "Eddystone RESERVED"
        resultsArray = [{"type": type}]
        return resultsArray

    if dataString[38:46] == '4c000215':
        """
        Selects parts of the bluetooth packets.
        """
        type = "iBeacon"
        uuid = dataString[46:54] + "-" + dataString[54:58] + "-" + dataString[58:62] + "-" + dataString[62:66] + "-" + dataString[66:78]
        major = dataString[78:82]
        minor = dataString[82:86]
        majorVal = int("".join(major.split()[::-1]), 16)
        minorVal = int("".join(minor.split()[::-1]), 16)
        """
        Organises Mac Address to display properly
        """
        scrambledAddress = dataString[14:26]
        fixStructure = iter("".join(reversed([scrambledAddress[i:i+2] for i in range(0, len(scrambledAddress), 2)])))
        macAddress = ':'.join(a+b for a,b in zip(fixStructure, fixStructure))
        rssi, = struct.unpack("b", packet[packetOffset -1])

        resultsArray = [{"type": type, "uuid": uuid, "major": majorVal, "minor": minorVal, "rssi": rssi, "macAddress": macAddress}]

        return resultsArray

    return results
这是修改后的BeaconScanner.py文件,如果扫描器通过mac地址找到想要的信标,该文件将打印“工作”

import ScanUtility
import bluetooth._bluetooth as bluez

#Set bluetooth device. Default 0.
dev_id = 0
try:
    sock = bluez.hci_open_dev(dev_id)
    print ("\n *** Looking for BLE Beacons ***\n")
    print ("\n *** CTRL-C to Cancel ***\n")
except:
    print ("Error accessing bluetooth")

ScanUtility.hci_enable_le_scan(sock)
#Scans for iBeacons
try:
    while True:
        returnedList = ScanUtility.parse_events(sock, 10)
        for macAddress in returnedList:
            if macAddress == "e2:e3:23:d1:b0:54":
            print("Works")
            else:
            print("Nope")
except KeyboardInterrupt:
    pass

但是,修改后的文件总是打印“Nope”。我认为if语句中的“macAddress”部分不能用来识别信标。代码中需要更改哪些内容才能通过if语句中的mac地址识别信标?

根据
scanputility.py
的来源,函数似乎返回一个dict列表,这有点奇怪。您应按如下方式查询dict:

for item in returnedList:
    try:
        if item['macAddress'] == "e2:e3:23:d1:b0:54":
            print("Works")
        else:
            print("Nope")
    except KeyError:
        print('MAC Address is missing')

注意,我添加了一个try/except语句来处理dict中不存在
macAddress
键的情况。只有当dict不是defaultdict的子类时,这才有效。

根据
scanputility.py
的源代码,函数似乎返回一个dict的列表,这有点奇怪。您应按如下方式查询dict:

for item in returnedList:
    try:
        if item['macAddress'] == "e2:e3:23:d1:b0:54":
            print("Works")
        else:
            print("Nope")
    except KeyError:
        print('MAC Address is missing')

请注意,我添加了一个try/except语句来处理dict中不存在
macAddress
键的情况。只有当dict不是defaultdict的子类时,这才起作用。

通过mac地址搜索信标并不总是一个好的解决方案,因为信标可能使用了默认地址

您确定您要查找的mac地址曾经广播过吗

您的代码似乎也只返回iBeacons的mac地址

关于这段代码,我注意到的另一点是,它通过直接调用hci套接字绕过系统上运行的
Bluetooth
。这通常不是一个好主意,需要使用根特权运行python脚本

避免这种情况的一种方法是使用。下面是一个例子,当它看到感兴趣的mac地址时,打印出信标数据和一条消息。此代码需要和

import argparse
从gi.repository导入GLib
从pydbus导入SystemBus
导入uuid
设备接口='org.bluez.Device1'
删除\u list=set()
def stop_scan():
“”“停止设备发现并退出事件循环”“”
adapter.StopDiscovery()
mainloop.quit()
def clean_信标():
"""
BlueZ D-Bus API不显示重复项。这是一个
用于删除已找到的设备的变通方法
发现期间
"""
未找到=设置()
对于删除列表中的rm_dev:
尝试:
adapter.RemoveDevice(rm_-dev)
除了作为错误的GLib.Error:
找不到。添加(rm\U开发)
对于在未找到的情况下丢失:
删除列表。删除(丢失)
def过程_eddystone(数据):
“”“以可读格式打印Eddystone数据”“”
_url_前缀_方案=['http://www.', 'https://www.',
'http://'、'https://'、]
_url_encoding=['.com/'、'.org/'、'.edu/'、'.net/'、'.info/',
“.biz/”、“.gov/”、“.com”、“.org”、“.edu”,
“.net”、“.info”、“.biz”、“.gov”]
tx_pwr=int.from_字节([data[1]],“big”,signed=True)
#Eddystone UID信标格式
如果数据[0]==0x00:
名称空间_id=int.from_字节(数据[2:12],'big')
实例_id=int.from_字节(数据[12:18],'big')
打印(f'\t\tDestone UID:{namespace\u id}-{instance\u id}\u2197{tx\u pwr}')
#Eddystone URL信标格式
elif数据[0]==0x10:
前缀=数据[2]
编码的url=数据[3:]
完整url=\U url\U前缀\U方案[前缀]
对于编码url中的字母:
如果字母