Skip to content

Commit

Permalink
Gatt lib (pybluez) removed from magicblueshell and from setup.py. Blu…
Browse files Browse the repository at this point in the history
…epy is now used everywhere as the default bluetooth library
  • Loading branch information
Betree committed Sep 20, 2016
1 parent e7159e1 commit 32aa1e7
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 43 deletions.
12 changes: 1 addition & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,14 @@ language / platform.
On the [research/bluetooth branch](https://github.com/Betree/pyMagicBlue/tree/research/bluetooth) you'll also find capture of bluetooth packets exchanged
between Android and the bulb (open hci_capture.log with Wireshark).

Tested on Linux only. I'll be happy to get your feedback on other platforms !
Tested on Linux and Raspberry Pi. I'll be happy to get your feedback on other platforms !

## Installation
### Linux
You must use python 3+ and have a proper Bluetooth 4.0 interface installed on your machine.

sudo apt-get install libbluetooth-dev
pip install git+https://github.com/Betree/pyMagicBlue.git

### Raspberry Pi
Gattlib may cause you some troubles if you're trying to set this project up for a Raspberry Pi. Fortunately [Mark Otting](https://github.com/b0tting) proposed a solution for this :

Pip started installing gattlib, then handed something over to gcc and that crapped out,
often "freezing" the Pi. It turns out that whatever it was that gattlib needed compiling
ran the pi out of memory. The solution was to increase swap space to 512mb (or 1024mb on
a 256mb memory RPI. Also note that Raspbian uses dphys-swapfile). It takes 30 minutes or
so but succesfully compiled after that.

## Usage

**Library needs root permissions to use Bluetooth features.**
Expand Down
2 changes: 1 addition & 1 deletion magicblue/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

from magicblue.magicbluelib import MagicBlue

__version__ = "0.1"
__version__ = "0.2"

4 changes: 2 additions & 2 deletions magicblue/magicbluelib.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ def disconnect(self):

def is_connected(self):
"""
:return: currently not supported anymore
:return: True if connected
"""
raise Exception("is_connected is not supported by bluepy library")
return self._connection

def set_warm_light(self, intensity=1.0):
"""
Expand Down
63 changes: 35 additions & 28 deletions magicblue/magicblueshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
# usage : python magicblue.py
# python_version : 3.4
# ========================================================================================

import argparse
import logging
import os
import sys
import time
import webcolors
from gattlib import DiscoveryService
from bluepy.btle import Scanner, DefaultDelegate
from sys import platform as _platform
from magicblue.magicbluelib import MagicBlue
from magicblue import __version__
Expand All @@ -24,9 +24,12 @@

class MagicBlueShell:
def __init__(self, bluetooth_adapter):
# List available commands and their usage. 'con_required' define if we need to be connected to a device for
# the command to run
self.available_cmds = [
{'cmd': 'help', 'func': self.list_commands, 'params': '', 'help': 'Show this help', 'con_required': False},
{'cmd': 'list_devices', 'func': self.cmd_list_devices, 'params': '', 'help': 'List Bluetooth LE devices in range', 'con_required': False},
{'cmd': 'ls', 'func': self.cmd_list_devices, 'params': '', 'help': 'Alias for list_devices', 'con_required': False},
{'cmd': 'connect', 'func': self.cmd_connect, 'params': 'mac_address', 'help': 'Connect to light bulb', 'con_required': False},
{'cmd': 'disconnect', 'func': self.cmd_disconnect, 'params': '', 'help': 'Disconnect from current light bulb', 'con_required': True},
{'cmd': 'set_color', 'func': self.cmd_set_color, 'params': 'name|hexvalue', 'help': "Change bulb's color", 'con_required': True},
Expand All @@ -39,15 +42,19 @@ def __init__(self, bluetooth_adapter):

def start_interactive_mode(self):
print('Magic Blue interactive shell v{}'.format(__version__))
print('Type "help" to see what you can do')

try:
str_cmd = ''
while str_cmd != 'exit':
str_cmd = input('> ')
self.exec_cmd(str_cmd)
except EOFError: # Catch CTRL+D
self.cmd_exit()
print('Type "help" for a list of available commands')

str_cmd = ''
while str_cmd != 'exit':
try:
str_cmd = input('> ').strip()
if str_cmd:
self.exec_cmd(str_cmd)
except (EOFError, KeyboardInterrupt): # Catch Ctrl+D / Ctrl+C
self.cmd_exit()
return
except Exception as e:
logger.error('Unexpected error with command "{}": {}'.format(str_cmd, str(e)))

def exec_cmd(self, str_cmd):
cmd = self._get_command(str_cmd)
Expand All @@ -70,30 +77,21 @@ def print_usage(self, str_cmd):

def cmd_list_devices(self, *args):
try:
service = DiscoveryService(self.bluetooth_adapter)
except RuntimeError as e:
logger.error('Problem with the Bluetooth adapter : {}'.format(e))
return False

print('Listing Bluetooth LE devices in range. Press CTRL+C to stop searching.')
print('{: <12} {: <12}'.format('Name', 'Mac address'))
print('{: <12} {: <12}'.format('----', '-----------'))

try:
while 42:
for device_mac, device_name in service.discover(2).items():
print('{: <12} {: <12}'.format(device_name, device_mac))
print('---------------')
time.sleep(1)
scanner = Scanner().withDelegate(ScanDelegate())
print('Listing Bluetooth LE devices in range for 5 minutes. Press CTRL+C to stop searching.')
print('{: <12} {: <12}'.format('Name', 'Mac address'))
print('{: <12} {: <12}'.format('----', '-----------'))
scanner.scan(350)
except KeyboardInterrupt:
print('\n')
except RuntimeError as e:
logger.error('Error while trying to list bluetooth devices : {}'.format(e))
logger.error('Problem with the Bluetooth adapter : {}'.format(e))
return False

def cmd_connect(self, *args):
self._magic_blue = MagicBlue(args[0][0])
self._magic_blue.connect(self.bluetooth_adapter)
logger.info('Connected : {}'.format(self._magic_blue.is_connected()))
logger.info('Connected')

def cmd_disconnect(self, *args):
self._magic_blue.disconnect()
Expand Down Expand Up @@ -147,6 +145,15 @@ def _get_command(self, str_cmd):
return next((item for item in self.available_cmds if item['cmd'] == str_cmd), None)


class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)

def handleDiscovery(self, dev, is_new_device, is_new_data):
if is_new_device:
dev_name = dev.getValueText(9).split('\x00')[0]
print('{: <12} {: <12}'.format(dev_name, dev.addr))

def get_params():
parser = argparse.ArgumentParser(description='Python tool to control Magic Blue bulbs over Bluetooth')
parser.add_argument('-l', '--list_commands', dest='list_commands', help='List available commands')
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
license='MIT',
packages=['magicblue'],
install_requires=[
'pybluez',
'bluepy',
'webcolors'
],
Expand Down

0 comments on commit 32aa1e7

Please sign in to comment.