Skip to content

Commit

Permalink
Version 0.6.0
Browse files Browse the repository at this point in the history
Updated to MetaWear-CppAPI version 0.6.0
Removed now deprecated 64-bit special handling.
Replaced printout logging with proper logging module usage.
  • Loading branch information
hbldh committed Oct 31, 2016
1 parent 7d63f20 commit 2f5e8ab
Show file tree
Hide file tree
Showing 28 changed files with 198 additions and 146 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v0.6.0 (2016-10-31)
===================
- Using MetaWear-CppAPI version 0.6.0
- Replaced print-logging with proper logging module usage.
- Removed 64-bit special handling that was no longer needed.

v0.5.2 (2016-10-13)
===================
- Temperature Module
Expand Down
11 changes: 0 additions & 11 deletions docs/source/backends/pygatt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,3 @@ Code can be found on `Github <https://github.com/peplin/pygatt>`_.

.. automodule:: pymetawear.backends.pygatt
:members:


PyMetaWearGATTToolBackend
-------------------------

Some parts of the ``gatttool`` connection client did not work
properly with the MetaWear boards.
Right now, these bugs are circumvented by overriding the offending methods.

.. automodule:: pymetawear.backends.pygatt.gatttool
:members:
6 changes: 3 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ Installation

.. code-block:: bash
$ pip install git+git://github.com/hbldh/pymetawear.git
$ pip install pymetawear
Currently, only the `pygatt <https://github.com/peplin/pygatt>`_ communication
backend is installed by default. The other backends can be installed as extras:

.. code-block:: bash
$ pip install git+git://github.com/hbldh/pymetawear.git[pybluez]
$ pip install pymetawear[pybluez]
or

.. code-block:: bash
$ pip install git+git://github.com/hbldh/pymetawear.git[bluepy]
$ pip install pymetawear[bluepy]
Requirements for ``pymetawear``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
6 changes: 1 addition & 5 deletions examples/raw/accelerometer.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,7 @@ def acc_callback(data):
libmetawear.mbl_mw_acc_write_acceleration_config(c.board)

print("Subscribing to accelerometer signal...")
if platform.architecture()[0] == '64bit':
libmetawear.mbl_mw_acc_get_acceleration_data_signal.restype = c_long
data_signal = c_long(libmetawear.mbl_mw_acc_get_acceleration_data_signal(c.board))
else:
data_signal = libmetawear.mbl_mw_acc_get_acceleration_data_signal(c.board)
data_signal = libmetawear.mbl_mw_acc_get_acceleration_data_signal(c.board)
libmetawear.mbl_mw_datasignal_subscribe(data_signal, _acc_callback)
print("Enable acc sampling on board...")
libmetawear.mbl_mw_acc_enable_acceleration_sampling(c.board)
Expand Down
6 changes: 1 addition & 5 deletions examples/raw/gyroscope.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,7 @@ def _callback(data):
print("Write gyroscope config....")
libmetawear.mbl_mw_gyro_bmi160_write_config(c.board)
print("Subscribing to gyroscope signal...")
if platform.architecture()[0] == '64bit':
libmetawear.mbl_mw_gyro_bmi160_get_rotation_data_signal.restype = c_long
data_signal = c_long(libmetawear.mbl_mw_gyro_bmi160_get_rotation_data_signal(c.board))
else:
data_signal = libmetawear.mbl_mw_gyro_bmi160_get_rotation_data_signal(c.board)
data_signal = libmetawear.mbl_mw_gyro_bmi160_get_rotation_data_signal(c.board)
libmetawear.mbl_mw_datasignal_subscribe(data_signal, the_callback)
print("Enable gyro sampling on board...")
libmetawear.mbl_mw_gyro_bmi160_enable_rotation_sampling(c.board)
Expand Down
6 changes: 1 addition & 5 deletions examples/raw/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ def switch_callback(data):


# Subscribe
if platform.architecture()[0] == '64bit':
libmetawear.mbl_mw_switch_get_state_data_signal.restype = c_long
data_signal = c_long(libmetawear.mbl_mw_switch_get_state_data_signal(c.board))
else:
data_signal = libmetawear.mbl_mw_switch_get_state_data_signal(c.board)
data_signal = libmetawear.mbl_mw_switch_get_state_data_signal(c.board)
fcn_dptr = Fn_DataPtr(switch_callback)
libmetawear.mbl_mw_datasignal_subscribe(data_signal, fcn_dptr)

Expand Down
9 changes: 1 addition & 8 deletions examples/raw/temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,7 @@ def temperature_callback(data):
channel = 0

# Subscribe to notifications
if platform.architecture()[0] == '64bit':
libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal.restype = c_long
data_signal = c_long(
libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(
c.board, channel))
else:
data_signal = libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(
c.board, channel)
data_signal = libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(c.board, channel)
fcn_dptr = Fn_DataPtr(temperature_callback)
libmetawear.mbl_mw_datasignal_subscribe(data_signal, fcn_dptr)

Expand Down
2 changes: 1 addition & 1 deletion examples/temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from pymetawear.client import MetaWearClient

address = scan_and_select_le_device()
c = MetaWearClient(str(address), 'pygatt', timeout=10, debug=False)
c = MetaWearClient(str(address), 'pygatt', timeout=10, debug=True)
print("New client created: {0}".format(c))


Expand Down
2 changes: 1 addition & 1 deletion pymetawear/Metawear-CppAPI
41 changes: 31 additions & 10 deletions pymetawear/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,32 @@
# -----------------------------------------------------------------------------

import os
import sys
import platform
import glob
from ctypes import cdll, c_longlong
from ctypes import cdll

from pymetawear.mbientlab.metawear.core import Fn_DataPtr, Fn_VoidPtr_Int
from pymetawear.mbientlab.metawear.functions import setup_libmetawear
from pymetawear.utils import IS_64_BIT

# Logging solution inspired by Hitchhiker's Guide to Python and Requests
# Set default logging handler to avoid "No handler found" warnings.
import logging
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass

logging.getLogger(__name__).addHandler(NullHandler())

# Version information.
__version__ = '0.5.2'
__version__ = '0.6.0'
version = __version__ # backwards compatibility name
version_info = (0, 5, 2)
version_info = (0, 6, 0)

# Find and import the built MetaWear-CPP shared library.
if os.environ.get('METAWEAR_LIB_SO_NAME') is not None:
libmetawear = cdll.LoadLibrary(os.environ["METAWEAR_LIB_SO_NAME"])
else:
Expand All @@ -34,9 +47,17 @@

setup_libmetawear(libmetawear)

# Alleviating Segfault causing pointer errors in 64-bit Python.
if IS_64_BIT:
libmetawear.mbl_mw_datasignal_subscribe.argtypes = [c_longlong, Fn_DataPtr]
libmetawear.mbl_mw_datasignal_unsubscribe.argtypes = [c_longlong, ]
libmetawear.mbl_mw_datasignal_log.argtypes = [c_longlong, Fn_DataPtr]
libmetawear.mbl_mw_datasignal_read.argtypes = [c_longlong]

def add_stream_logger(stream=sys.stdout, level=logging.DEBUG):
"""
Helper for quickly adding a StreamHandler to the logger. Useful for
debugging.
Returns the handler after adding it.
"""
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(stream=stream)
handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
logger.addHandler(handler)
logger.setLevel(level)
logger.debug('Added a {0} logging handler to logger: {1}'.format(stream.name, __name__))
return handler
26 changes: 16 additions & 10 deletions pymetawear/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
import time
from ctypes import byref
import uuid
import logging

from pymetawear import libmetawear
from pymetawear.exceptions import PyMetaWearException
from pymetawear.mbientlab.metawear.core import BtleConnection, Fn_VoidPtr_GattCharPtr, \
Fn_VoidPtr_GattCharPtr_ByteArray, Fn_VoidPtr_Int
from pymetawear.specs import METAWEAR_SERVICE_NOTIFY_CHAR
from pymetawear.utils import string_types
from pymetawear.compat import string_types

log = logging.getLogger(__name__)


class BLECommunicationBackend(object):
Expand All @@ -34,6 +37,9 @@ def __init__(self, address, interface=None,
self._debug = debug
self._timeout = timeout

if debug:
log.setLevel(logging.DEBUG)

self._initialization_status = -1

self._requester = None
Expand Down Expand Up @@ -103,8 +109,7 @@ def disconnect(self):

def subscribe(self, characteristic_uuid, callback):
self._subscribe(characteristic_uuid, callback)
if self._debug:
self._print_debug_output("Subscribe", characteristic_uuid, [])
self._print_debug_output("Subscribe", characteristic_uuid, [])

def mbl_mw_read_gatt_char(self, board, characteristic):
"""Read the desired data from the MetaWear board.
Expand All @@ -123,8 +128,7 @@ def mbl_mw_read_gatt_char(self, board, characteristic):
libmetawear.mbl_mw_metawearboard_char_read(
self.board, characteristic, sb.raw, len(sb.raw))

if self._debug:
self._print_debug_output("Read", characteristic_uuid, response)
self._print_debug_output("Read", characteristic_uuid, response)

def mbl_mw_write_gatt_char(self, board, characteristic, command, length):
"""Write the desired data to the MetaWear board.
Expand Down Expand Up @@ -157,13 +161,12 @@ def write_gatt_char_by_uuid(self, characteristic_uuid, data_to_send):
# Callback methods

def _initialized_fcn(self, board, status):
if self._debug:
print("{0} initialized with status {1}.".format(self, status))
log.debug("{0} initialized with status {1}.".format(self, status))
self._initialization_status = status

def handle_notify_char_output(self, handle, value):
if self._debug:
self._print_debug_output("Notify", handle, value)

self._print_debug_output("Notify", handle, value)

if handle == self._notify_char_handle:
sb = self.notify_response_to_str(value)
Expand Down Expand Up @@ -206,6 +209,9 @@ def _mbl_mw_characteristic_2_uuids(characteristic):
characteristic.uuid_low))

def _print_debug_output(self, action, handle_or_char, data):
if not self._debug:
return

if data and isinstance(data[0], int):
data_as_hex = " ".join(["{:02x}".format(b) for b in data])
else:
Expand All @@ -218,7 +224,7 @@ def _print_debug_output(self, action, handle_or_char, data):
else:
handle = -1

print("{0:<6s} 0x{1:04x}: {2}".format(action, handle, data_as_hex))
log.debug("{0:<6s} 0x{1:04x}: {2}".format(action, handle, data_as_hex))

def sleep(self, t):
"""Make backend sleep."""
Expand Down
17 changes: 10 additions & 7 deletions pymetawear/backends/bluepy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
import uuid
import warnings
from ctypes import create_string_buffer
import logging

from bluepy.btle import Peripheral, ADDR_TYPE_RANDOM, BTLEException, DefaultDelegate, Characteristic

from pymetawear.exceptions import PyMetaWearException, PyMetaWearConnectionTimeout
from pymetawear.utils import range_, string_types, bytearray_to_str
from pymetawear.compat import range_, string_types, bytearray_to_str
from pymetawear.backends import BLECommunicationBackend

__all__ = ["BluepyBackend"]

log = logging.getLogger(__name__)


class BluepyDelegate(DefaultDelegate):

Expand All @@ -47,6 +50,8 @@ def __init__(self, address, interface=None, async=False, timeout=None, debug=Fal
self._primary_services = {}
self._characteristics_cache = {}
self._peripheral = None
if debug:
log.setLevel(logging.DEBUG)

warnings.warn("Bluepy backend does not handle notifications properly yet.", RuntimeWarning)

Expand Down Expand Up @@ -86,13 +91,11 @@ def requester(self):
"""

if self._peripheral is None:
if self._debug:
print("Creating new Peripheral...")
log.info("Creating new BluePy Peripheral...")
self._peripheral = Peripheral()

if not self._is_connected:
if self._debug:
print("Connecting Peripheral...")
log.debug("Connecting BluePy Peripheral...")
self._peripheral.connect(
self._address, addrType=ADDR_TYPE_RANDOM,
iface=str(self._interface).replace('hci', ''))
Expand Down Expand Up @@ -122,10 +125,10 @@ def _subscription_loop(self):

while True:
try:
print("Waiting for notification")
log.debug("Waiting for notification")
self.requester.waitForNotifications(1.0)
except BTLEException as e:
print("Error waiting: {0}".format(e))
log.error("Error waiting: {0}".format(e))
pass

# Read and Write methods
Expand Down
14 changes: 9 additions & 5 deletions pymetawear/backends/pybluez/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@
import time
import uuid
from ctypes import create_string_buffer
import logging

from bluetooth.ble import GATTRequester, GATTResponse

from pymetawear.exceptions import PyMetaWearException, PyMetaWearConnectionTimeout
from pymetawear.utils import range_, string_types, bytearray_to_str
from pymetawear.compat import range_, string_types, bytearray_to_str
from pymetawear.backends import BLECommunicationBackend

__all__ = ["PyBluezBackend"]

log = logging.getLogger(__name__)


class Requester(GATTRequester):

Expand All @@ -45,6 +48,8 @@ def __init__(self, address, interface=None, async=True, timeout=None, debug=Fals
self._primary_services = {}
self._characteristics_cache = {}
self._response = GATTResponse()
if debug:
log.setLevel(logging.DEBUG)

super(PyBluezBackend, self).__init__(
address, interface, async, 10.0 if timeout is None else timeout, debug)
Expand All @@ -65,14 +70,13 @@ def requester(self):
"""

if self._requester is None:
if self._debug:
print("Creating new GATTRequester...")

log.info("Creating new GATTRequester...")
self._requester = Requester(self.handle_notify_char_output, self._address,
False, self._interface)

if not self._requester.is_connected():
if self._debug:
print("Connecting GATTRequester...")
log.info("Connecting GATTRequester...")
self._requester.connect(wait=False, channel_type='random')
# Using manual waiting since gattlib's `wait` keyword does not work.
t = 0.0
Expand Down
Loading

0 comments on commit 2f5e8ab

Please sign in to comment.