SimplePyBLE - Python bindings for SimpleBLE

Overview

SimplePyBLE - Python bindings for SimpleBLE

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

All specific operating system quirks are handled to provide a consistent behavior across all platforms. Each major version of the library will have a stable API that will be fully forwards compatible.

If you want to use the library and need help. Please reach out! You can find me at: kevin at dewald dot me

Instalation

pip install simplepyble

Usage

Please review the provided examples in the source code. They are all self-contained and can be run from the command line. More documentation will be available soon.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

All components within this project that have not been bundled from external creators, are licensed under the terms of the MIT Licence.

Comments
  • Repeated read gives always the same value

    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?

    opened by piotromt 11
  • peripheral.identifier() in the scan example always return an empty string.

    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.

    opened by zapta 5
  • Please expose the pairing related methods in the Python API

    Please expose the pairing related methods in the Python API

    These two pairing related methods are not reflected in the Python API.

    Please add them there.

    https://github.com/OpenBluetoothToolbox/SimpleBLE/blob/main/include/simpleble/Peripheral.h#L32

    opened by zapta 3
  • peripheral.read: UnicodeDecodeError: 'utf-8' codec can't decode byte

    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>
    
    opened by zenbooster 2
  • How to pair with BLE device?

    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.

    opened by inamghouss 1
  • run example scan.py error: Process finished with exit code -1073741819 (0xC0000005)

    run example scan.py error: Process finished with exit code -1073741819 (0xC0000005)

    some details window10 python => 3.8.5 simplepyble => 0.0.5

    sometimes return an empty string for all devices, sometimes return error Process finished with exit code -1073741819 (0xC0000005)

    opened by fanleung 0
Releases(v0.0.5)
  • v0.0.5(Jun 13, 2022)

    [0.0.5] - 2022-06-12

    Added

    • Python's Global Interpreter Lock (GIL) will be released during Peripheral.connect()
    • Keep-alive policies for function objects passed into SimplePyBLE.
    Source code(tar.gz)
    Source code(zip)
  • v0.0.4(Feb 14, 2022)

  • v0.0.3(Feb 13, 2022)

    [0.0.3] - 2022-01-22

    Fixed

    • write_request and write_command functions would accept strings instead of bytes as payloads. (Thanks kaedenbrinkman!)
    Source code(tar.gz)
    Source code(zip)
  • v0.0.2(Jan 16, 2022)

  • v0.0.1(Jan 11, 2022)

Owner
Open Bluetooth Toolbox
Tools and code for Bluetooth development
Open Bluetooth Toolbox
My HA controller for veg and flower rooms

HAGrowRoom My HA controller for veg and flower rooms I will do my best to keep this updated as I change, add and improve. System heavily uses custom t

4 May 25, 2022
Скрипт позволяет заводить задачи в Панель мониторинга YouTrack на основе парсинга сайта safe-surf.ru

Скрипт позволяет заводить задачи в Панель мониторинга YouTrack на основе парсинга сайта safe-surf.ru

Bad_karma 3 Feb 12, 2022
qecsim is a Python 3 package for simulating quantum error correction using stabilizer codes.

qecsim qecsim is a Python 3 package for simulating quantum error correction using stabilizer codes.

44 Dec 20, 2022
The official Repository wherein newbies into Open Source can Contribute during the Hacktoberfest 2021

Hacktoberfest 2021 Get Started With your first Contrinution/Pull Request : Fork/Copy the repo by clicking the right most button on top of the page. Go

HacOkars 25 Aug 20, 2022
A TODO-list tool written in Python

PyTD A TODO-list tool written in Python. Its goal is to provide a stable posibility to get a good view over all your TODOs motivate you to actually fi

1 Feb 12, 2022
Library for mocking AsyncIOMotorClient built on top of mongomock.

mongomock-motor Best effort mock for AsyncIOMotorClient (Database, Collection, e.t.c) built on top of mongomock library. Example / Showcase from mongo

Michael Kryukov 43 Jan 04, 2023
Example applications, dashboards, scripts, notebooks, and other utilities built using Polygon.io

Polygon.io Examples Example applications, dashboards, scripts, notebooks, and other utilities built using Polygon.io. Examples Preview Name Type Langu

Tim Paine 4 Jun 01, 2022
A shim for the typeshed changes in mypy 0.900

types-all A shim for the typeshed changes in mypy 0.900 installation pip install types-all why --install-types is annoying, this installs all the thin

Anthony Sottile 28 Oct 20, 2022
A Python application that helps users determine their calorie intake, and automatically generates customized weekly meal and workout plans based on metrics computed using their physical parameters

A Python application that helps users determine their calorie intake, and automatically generates customized weekly meal and workout plans based on metrics computed using their physical parameters

Anam Iqbal 1 Jan 13, 2022
Built as part of an assignment for S5 OOSE Subject CSE

Installation Steps: Download and install Python from here based on your operating system. I have used Python v3.8.10 for this. Clone the repository gi

Abhinav Rajesh 2 Sep 09, 2022
An useful scripts for Misskey

misskey-scripts This place storing useful scripts which made by me. icon-repair Repair broken remote user's icon.

CyberRex 5 Sep 09, 2022
An kind of operating system portal to a variety of apps with pure python

pyos An kind of operating system portal to a variety of apps. Installation Run this on your terminal: git clone https://github.com/arjunj132/pyos.git

1 Jan 22, 2022
An addin for Autodesk Fusion 360 that lets you view your design in a Looking Glass Portrait 3D display

An addin for Autodesk Fusion 360 that lets you view your design in a Looking Glass Portrait 3D display

Brian Peiris 12 Nov 02, 2022
Material de apoio da oficina de SAST apresentada pelo CAIS no Webinar de 28/05/21.

CAIS-CAIS Conjunto de Aplicações Intencionamente Sem-Vergonha do CAIS Material didático do Webinar "EP1. Oficina - Práticas de análise estática de cód

Fausto Filho 14 Jul 25, 2022
A simple single-color identicon generator

Identicons What are identicons? Setup: git clone https://github.com/vjdad4m/identicons.git cd identicons pip3 install -r requirements.txt chmod +x

Adam Vajda 1 Oct 31, 2021
Blender Light Manipulation - A script that makes it easier to work with light

Blender Light Manipulation A script that makes it easier to work with light 1. Wstęp W poniższej dokumentacji przedstawiony zostanie skrypt, który swo

Tomasz 1 Oct 19, 2021
Fortnite StW Claimer for Daily Rewards, Research Points and free Llamas.

Fortnite Save the World Daily Reward, Research Points & free Llama Claimer This program allows you to claim Save the World Daily Reward, Research Poin

PRO100KatYT 27 Dec 22, 2022
msImpersonate - User account impersonation written in pure Python3

msImpersonate v1.0 msImpersonate is a Python-native user impersonation tool that is capable of impersonating local or network user accounts with valid

Joe Helle 90 Dec 16, 2022
A tool to replace all osu beatmap backgrounds at once.

OsuBgTool A tool to replace all osu beatmap backgrounds at once. Requirements You need to have python 3.6 or newer installed. That's it. How to Use Ju

Aditya Gupta 1 Oct 24, 2021
Sentiment Based Product Recommendation System

Sentiment Based Product Recommendation System The e-commerce business is quite p

Sumit Sahay 2 Jan 15, 2022