GithubHelp home page GithubHelp logo

openbluetoothtoolbox / python_simpleble Goto Github PK

View Code? Open in Web Editor NEW
25.0 5.0 5.0 19 KB

The ultimate fully-fledged cross-platform Python BLE library, designed for simplicity and ease of use.

License: MIT License

CMake 5.93% Python 55.42% C++ 38.65%
python3 bluetooth cross-platform windows linux macos

python_simpleble's Introduction

python_simpleble's People

Contributors

kdewald avatar zenbooster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

python_simpleble's Issues

peripheral.identifier() in the scan example always return an empty string.

I am running the scan.py example on windows 10 pro, Python 3.9.5. Everything works well except that the device names are not printed. I think it's supposed to come from peripheral.identifier() but it seems to return an empty string for all devices.

By device name I mean the human friendly name that we see in the bluetooth device setting screens of Windows, iPhone, etc.

peripheral.read: UnicodeDecodeError: 'utf-8' codec can't decode byte

Windows 10; python 3.9.7

import simplepyble
import random
import threading
import time
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

def encrypt(key, data):
  k = AES.new(bytes(reversed(key)), AES.MODE_ECB)
  data = reversed(list(k.encrypt(bytes(reversed(data)))))
  rev = []
  for d in data:
    rev.append(d)
  return rev


def key_encrypt(name, password, key):
  name = name.ljust(16, chr(0))
  password = password.ljust(16, chr(0))
  data = [ord(a) ^ ord(b) for a,b in zip(name,password)]
  return encrypt(key, data)

class dimond:
  def __init__(self, vendor, mac, name, password, mesh=None, callback=None):
    self.vendor = vendor
    self.mac = mac
    self.macarray = mac.split(':')
    self.name = name
    self.password = password
    self.callback = callback
    self.mesh = mesh
    self.packet_count = random.randrange(0xffff)
    self.macdata = [int(self.macarray[5], 16), int(self.macarray[4], 16), int(self.macarray[3], 16), int(self.macarray[2], 16), int(self.macarray[1], 16), int(self.macarray[0], 16)]
  
  def __done__(self):
    self.peripheral.disconnect()

  def set_sk(self, sk):
    self.sk = sk

  def connect(self):
    #self.device = btle.Peripheral(self.mac, addrType=btle.ADDR_TYPE_PUBLIC)
    adapters = simplepyble.Adapter.get_adapters()

    if len(adapters) == 0:
        print("No adapters found")

    # Query the user to pick an adapter
    adapter = adapters[0]

    print(f"Selected adapter: {adapter.identifier()} [{adapter.address()}]")

    adapter.set_callback_on_scan_start(lambda: print("Scan started."))
    adapter.set_callback_on_scan_stop(lambda: print("Scan complete."))
    adapter.set_callback_on_scan_found(lambda peripheral: (peripheral.address() == self.mac) and print(f"Found {peripheral.identifier()} [{peripheral.address()}]"))

    # Scan for 5 seconds
    adapter.scan_for(5000)
    peripherals = adapter.scan_get_results()
    
    self.peripheral = None
    # Query the user to pick a peripheral
    for i, p in enumerate(peripherals):
        if p.address() == self.mac:
            self.peripheral = p
            break

    if (self.peripheral):
        connectable_str = "Connectable" if self.peripheral.is_connectable() else "Non-Connectable"
        print(f"{self.peripheral.identifier()} [{self.peripheral.address()}] - {connectable_str}")

        manufacturer_data = self.peripheral.manufacturer_data()
        for manufacturer_id, value in manufacturer_data.items():
            print(f"    Manufacturer ID: {manufacturer_id}")
            print(f"    Manufacturer data: {value}")

        print(f"Connecting to: {self.peripheral.identifier()} [{self.peripheral.address()}]")
        self.peripheral.connect()
        '''
        print("Successfully connected, listing services...")
        services = self.peripheral.services()
        for service in services:
            print(f"Service: {service.uuid}")
            for characteristic in service.characteristics:
                print(f"    Characteristic: {characteristic}")
        '''
        self.notification = '00010203-0405-0607-0809-0a0b0c0d1911'
        self.control = '00010203-0405-0607-0809-0a0b0c0d1912'
        self.pairing = '00010203-0405-0607-0809-0a0b0c0d1914'
       
        data = [0] * 16
        random_data = get_random_bytes(8)
        for i in range(8):
          data[i] = random_data[i]
        enc_data = key_encrypt(self.name, self.password, data)
        packet = [0x0c]
        packet += data[0:8]
        packet += enc_data[0:8]
        try:
          self.peripheral.write_request('00010203-0405-0607-0809-0a0b0c0d1910', self.pairing, bytes(packet))
          time.sleep(0.3)
          data2 = self.peripheral.read('00010203-0405-0607-0809-0a0b0c0d1910', self.pairing)
        except:
          raise Exception("Unable to connect")
        
        print('Ok!')

    else:
        print('BT device "{}" not found!'.format(target_mac))

target_mac = '08:65:f0:04:04:e1'

if __name__ == "__main__":
    network = dimond(0x0211, target_mac, "ZenggeMesh", "ZenggeTechnology")#, callback=callback)
    network.connect()
(base) D:\work\btdimmer>python btdimmer.py
Selected adapter: dongle [00:1a:7d:da:71:12]
Scan started.
Found abd8302448845239 [08:65:f0:04:04:e1]
Scan complete.
abd8302448845239 [08:65:f0:04:04:e1] - Connectable
    Manufacturer ID: 529
    Manufacturer data: b'\x11\x02\xe1\x04\x04\xf0\x02\x0f\x01\x02\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
Connecting to: abd8302448845239 [08:65:f0:04:04:e1]
Traceback (most recent call last):
  File "D:\work\btdimmer\btdimmer.py", line 109, in connect
    data2 = self.peripheral.read('00010203-0405-0607-0809-0a0b0c0d1910', self.pairing)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x86 in position 1: invalid start byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\work\btdimmer\btdimmer.py", line 122, in <module>
    network.connect()
  File "D:\work\btdimmer\btdimmer.py", line 111, in connect
    raise Exception("Unable to connect")
Exception: Unable to connect

(base) D:\work\btdimmer>

Repeated read gives always the same value

It seems that reading value from characteristic from peripheral never gets updated during one connection, multiple reads during the same connection always give me the same value, even when the characteristic is updated on the service side. I did a test, I created a peripheral with service with 2 text characteristics, A for writing and B for reading. On the service side, when A is written , B is updated. When I do the the connection to this peripheral and then the sequence: write - read - write different value - read, the second read gives me the value from the first read, it never gets updated. When I disconnect from peripheral and connect again, read gives me updated second value. Is this a "feature" or the bug?

How to pair with BLE device?

Hi,
I am using Library "simplepyble". It is looking very simple and easy to use but I didn't find any method or syntax for pairing or bonding in the examples. Can you please guide me on how I can pair my PC with my BLE device using "simplepyble".
Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.