Имя устройства Bluetooth и соответствующее имя последовательного порта в python

У меня есть устройство с поддержкой Bluetooth и удобным для пользователя именем «Sensor1». Это устройство использует профиль SPP. Чтобы попросить устройство начать передачу данных через Bluetooth, я должен написать '10111011' на COM-порту, соответствующем этому устройству, следующим образом:

ser = serial.Serial('COM5') 
ser.write('10111011')     

Проблема в том, что я не знаю, какой из COM-портов соответствует «Sensor1». Итак, я читаю реестр Windows, чтобы получить имя устройства:

import _winreg as reg
from itertools import count

key = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, 'HARDWARE\\DEVICEMAP\\SERIALCOMM')
for i in count():
    device, port = reg.EnumValue(key, i)[:2]
    print "Device name \"%s\" found at %s" % (device, port)

Все, что я получаю, это:

Device name \Device\Serial0 found at COM3
Device name \Device\BthModem16 found at COM4
Device name \Device\BthModem17 found at COM5

Как я могу получить имя устройства, как в:

service = bluetooth.find_service()
print service["name"]

person QuestionMark    schedule 11.11.2015    source источник


Ответы (3)


Я рекомендую вам сначала найти MAC-адрес, а затем найти COM-порт по MAC-адресу. Но я не уверен, что это лучший способ. Я тестировал этот код в Windows 10 и Python 3.5.

Чтобы найти MAC-адрес по понятному имени, используйте эту функцию:

import bluetooth
def find_bt_address_by_target_name(name):
    # sometimes bluetooth.discover_devices() failed to find all the devices
    MAX_COUNT = 3
    count = 0
    while True:
        nearby_devices = bluetooth.discover_devices()

        for btaddr in nearby_devices:
            if name == bluetooth.lookup_name( btaddr ):
                return btaddr

        count += 1
        if count > MAX_COUNT:
            return None
        print("Try one more time to find target device..")            

Затем найдите COM-порт по MAC-адресу. Это предполагает, что вы уже подключились к целевому устройству и включили порты SPP:

import winreg
import serial
import time

class BluetoothSpp:
    key_bthenum = r"SYSTEM\CurrentControlSet\Enum\BTHENUM"
    # IMPORTANT!! 
    # you need to change this by searching the registry
    DEBUG_PORT = 'C00000001'

    def get_spp_com_port(self, bt_mac_addr):
        print(bt_mac_addr)
        bt_mac_addr = bt_mac_addr.replace(':', '').upper()
        for i in self.gen_enum_key('', 'LOCALMFG'):
            print(i)
            for j in self.gen_enum_key(i, bt_mac_addr):
                print(j)
                if self.DEBUG_PORT in j:
                    subkey = self.key_bthenum+'\\'+ i+'\\'+j
                    port = self.get_reg_data(subkey, 'FriendlyName')
                    assert('Standard Serial over Bluetooth link' in port[0])
                    items = port[0].split()
                    port = items[5][1:-1]
                    print(port)
                    return port

    def gen_enum_key(self, subkey, search_str):
        hKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, self.key_bthenum + '\\' + subkey)

        try:
            i = 0
            while True:
                output = winreg.EnumKey(hKey, i)
                if search_str in output:
                    yield output
                i += 1

        except:
            pass

        winreg.CloseKey(hKey)

    def get_reg_data(self, subkey, name):
        hKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 
                            subkey)
        output = winreg.QueryValueEx(hKey, name) 
        winreg.CloseKey(hKey)
        return output

if __name__ == '__main__':
    mac_addr = '11:22:33:44:55:66'
    bt_spp = BluetoothSpp()
    com_port = bt_spp.get_spp_com_port(mac_addr)
person Youngmin Kim    schedule 23.11.2018

import bluetooth
decices = bluetooth.discover_devices()

Используя следующую библиотеку: https://pypi.python.org/pypi/PyBluez/< br> Вот несколько хороших примеров использования: https://people.csail.mit.edu/albert/bluez-intro/c212.html

Если вы не заинтересованы в использовании дополнительной библиотеки, вы всегда можете попытаться извлечь функцию обнаружения, относящуюся к Windows, которую можно найти здесь: /widcomm.py#L109" rel="nofollow">https://github.com/karulis/pybluez/blob/2a22e61fb21c27b47898c2674662de65162b485f/bluetooth/widcomm.py#L109

person Torxed    schedule 11.11.2015
comment
Ну я уже пользовался блютуз библиотекой. Тем не менее, в: service = bluetooth.find_service() и затем port = service["port"] у меня есть 2, которые не имеют ничего общего с COM5 в моем примере. - person QuestionMark; 11.11.2015
comment
@QuestionMark Правильно, да. Я посмотрел мимо двух строк, что было глупо с моей стороны. В настоящее время у меня нет устройств BlueTooth поблизости (на работе), но я предполагаю, что каждый объект в devices будет иметь ключ с именем port. вы используете find_service вместо обнаружения. Если я не ошибаюсь, это даст вам уже подключенное устройство и номер локального порта, используемый для доступа к этому устройству (для потоковой передачи данных). Вы ищете физический порт, который может быть найден в discover_devices, но опять же, я не могу подтвердить свои предположения, так как у меня поблизости нет Bluetooth-устройств. - person Torxed; 11.11.2015
comment
Думаю что ключа port для устройств в discover_devices нет. - person QuestionMark; 12.11.2015

Еще одно решение, которое сработало для меня.

import serial.tools.list_ports

#Find COM port with LookFor name
lookFor = "DG-1"
nb=discover_devices(lookup_names=True)
for addr,name in list(nb):
    if lookFor == name:
        break
    else:
        name = None
        addr = None
if name == lookFor:
    comPorts=list(serial.tools.list_ports.comports())
    addr=addr.translate(None,":")
    for COM,des,hwenu in comPorts :
        if addr in hwenu:
            break
if name!=None:
    print "COM=",COM,"   BTid=",name
else:
    print LookFor," not found."
person Kym    schedule 16.08.2019