|
1 | 1 | pyshimmer: Unofficial Python API for Shimmer Sensor devices
|
2 | 2 | ===========================================================
|
3 | 3 |
|
4 |
| -pyshimmer provides a Python API to work with the wearable sensor devices produced by Shimmer_. |
| 4 | +.. image:: https://travis-ci.com/seemoo-lab/pyshimmer.svg?branch=master |
| 5 | + :target: https://travis-ci.com/seemoo-lab/pyshimmer |
| 6 | + |
| 7 | +.. contents:: |
| 8 | + |
| 9 | +General Information |
| 10 | +------------------- |
| 11 | + |
| 12 | +pyshimmer provides a Python API to work with the wearable sensor devices produced by Shimmer_. The API is divided into |
| 13 | +three major components: |
| 14 | + |
| 15 | +* The Bluetooth API: An interface to communicate with the Shimmer LogAndStream firmware via Bluetooth |
| 16 | +* The UART API: An interface to communicate with the Shimmer while they are placed in a dock |
| 17 | +* The Reader API: An interface to read the binary files produced by the Shimmer devices |
5 | 18 |
|
6 | 19 | .. _Shimmer: http://www.shimmersensing.com/
|
| 20 | + |
| 21 | +Contributing |
| 22 | +------------ |
| 23 | +All code in this repository was produced as part of my Master thesis. This means that the API is not |
| 24 | +complete. Especially the Bluetooth and UART API do not feature all calls supported by the devices. However, the code |
| 25 | +provides a solid foundation to extend it where necessary. Please feel free to make contributions in case the code is |
| 26 | +missing required calls. |
| 27 | + |
| 28 | +Installation |
| 29 | +------------ |
| 30 | + |
| 31 | +The targeted plattform for this library is **Linux**. It has not been tested under other operating systems. In order to |
| 32 | +use all aspects of the library, you need to install the package itself, set up the Bluetooth interface, and possibly |
| 33 | +configure udev rules to ensure that the device names are consistent. |
| 34 | + |
| 35 | +pyshimmer Package |
| 36 | +^^^^^^^^^^^^^^^^^ |
| 37 | +In order to install the package itself, clone it and use pip to install it: |
| 38 | + |
| 39 | +.. code-block:: |
| 40 | +
|
| 41 | + git clone https://github.com/seemoo-lab/pyshimmer.git |
| 42 | + cd pyshimmer |
| 43 | + pip install . |
| 44 | +
|
| 45 | +If you want to run the tests, instead install the package with :code:`test` extras: |
| 46 | + |
| 47 | +.. code-block:: |
| 48 | +
|
| 49 | + pip install .[test] |
| 50 | +
|
| 51 | +You can then run the tests from the repository root by simply issuing: |
| 52 | + |
| 53 | +.. code-block:: |
| 54 | +
|
| 55 | + pytest |
| 56 | +
|
| 57 | +Creating udev rules for persistent device filenames |
| 58 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 59 | + |
| 60 | +When plugging a Shimmer dock into the host, Linux will detect two new serial interfaces and a block device representing |
| 61 | +the internal SD card of the Shimmer: |
| 62 | + |
| 63 | +* :code:`/dev/ttyUSB0` for the serial interface to the bootloader, |
| 64 | +* :code:`/dev/tty/USB1` for the serial interface to the device itself, |
| 65 | +* :code:`/dev/sdX` for the block device. |
| 66 | + |
| 67 | +When working with multiple docks and devices, keeping track of the names of the serial interfaces can be quite |
| 68 | +cumbersome, since udev simply names the devices in the order they are plugged in to the system. You can use udev rules |
| 69 | +to assign persistent names to the device files. Note that the rules do not actually match the Shimmer but the dock that |
| 70 | +it is located in. **This means that you need to always place the device in its respective dock**. |
| 71 | + |
| 72 | +The following section provides an example of how to handle two Shimmer docks, one of which is an ECG and the other a |
| 73 | +PPG device. |
| 74 | + |
| 75 | +Create a new udev rule file: :code:`/etc/udev/rules.d/10-shimmer.rules` and add the following contents: |
| 76 | + |
| 77 | +.. code-block:: |
| 78 | +
|
| 79 | + SUBSYSTEMS=="usb" ATTRS{bInterfaceNumber}!="00" GOTO="is_secondary_interface" |
| 80 | + SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor1>" ATTRS{idProduct}=="<id_product1>" ATTRS{serial}=="<id_serial1>" SYMLINK+="ttyPPGbl" |
| 81 | + SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor2>" ATTRS{idProduct}=="<id_product2>" ATTRS{serial}=="<id_serial2>" SYMLINK+="ttyECGbl" |
| 82 | + GOTO="end" |
| 83 | +
|
| 84 | + LABEL="is_secondary_interface" |
| 85 | + SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor1>" ATTRS{idProduct}=="<id_product1>" ATTRS{serial}=="<id_serial1>" SYMLINK+="ttyPPGdev" |
| 86 | + SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor2>" ATTRS{idProduct}=="<id_product2>" ATTRS{serial}=="<id_serial2>" SYMLINK+="ttyECGdev" |
| 87 | + GOTO="end" |
| 88 | +
|
| 89 | + LABEL="end" |
| 90 | +
|
| 91 | +You can also find the example file in :code:`conf/udev/10-shimmer.rules.example`. Distinguishing both Shimmer Docks and |
| 92 | +tty interfaces is somewhat difficult because the distinguishing attributes are spread across multiple devices in the |
| 93 | +USB device tree. The main distinguishing attribute is the serial ID of the dock. This allows to distinguish between the |
| 94 | +ECG and the PPG dock. The second step is to check if the bInterfaceNumber of the tty device is 00 (bootloader) or |
| 95 | +01 (device UART). Unfortunately, it is not possible to check attributes from different parents in a single rule and we |
| 96 | +need to use the Goto action to create an if clause around the bInterfaceNumber. |
| 97 | + |
| 98 | +In the file, you need to replace the |
| 99 | +:code:`<id_vendor1>`, :code:`<id_product1>`, and :code:`<id_serial1>` of the first device, and the :code:`<id_vendor2>`, |
| 100 | +:code:`<id_product2>`, and :code:`<id_serial2>` of the second device. You can find the values by scanning the |
| 101 | +:code:`dmesg` command after plugging in a Shimmer device. Here is an example: |
| 102 | + |
| 103 | +.. code-block:: |
| 104 | +
|
| 105 | + [144366.290357] usb 1-4.3: new full-speed USB device number 34 using xhci_hcd |
| 106 | + [144366.386661] usb 1-4.3: New USB device found, idVendor=<id_vendor>, idProduct=<id_product>, bcdDevice= 5.00 |
| 107 | + [144366.386668] usb 1-4.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3 |
| 108 | + [144366.386674] usb 1-4.3: Product: SHIMMER DOCK |
| 109 | + [144366.386679] usb 1-4.3: Manufacturer: FTDI |
| 110 | + [144366.386684] usb 1-4.3: SerialNumber: <id_serial> |
| 111 | +
|
| 112 | +Save the file and reload the rules for them to take effect: |
| 113 | + |
| 114 | + |
| 115 | +.. code-block:: |
| 116 | +
|
| 117 | + udevadm control --reload-rules && udevadm trigger |
| 118 | +
|
| 119 | +Configuring the Bluetooth Interface |
| 120 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 121 | +The library uses a :code:`tty` serial interface to communicate with the Shimmer over Bluetooth. Before you can use the |
| 122 | +library, you need to set up the serial channel appropriately. This has only been tested this under Arch Linux, but other |
| 123 | +Linux distributions should work as well. |
| 124 | + |
| 125 | +Requirements: |
| 126 | + |
| 127 | +* Functioning Bluetooth stack |
| 128 | +* The :code:`rfcomm` commandline tool. For Arch Linux, use the `bluez-rfcomm AUR <https://aur.archlinux.org/packages/bluez-rfcomm/>`_ package |
| 129 | +* The :code:`hcitool` commandline tool. For Arch Linux, use the `bluez-hcitool AUR <https://aur.archlinux.org/packages/bluez-hcitool/>`_ package |
| 130 | +* A Shimmer device with :code:`LogAndStream` firmware |
| 131 | + |
| 132 | +Scan for the device the find out its MAC address: |
| 133 | + |
| 134 | +.. code-block:: |
| 135 | +
|
| 136 | + hcitool scan |
| 137 | +
|
| 138 | +The MAC address of the listed Shimmer device should end with the *BT Radio ID* imprinted on the back of the device. |
| 139 | +Next, you can try and ping the device: |
| 140 | + |
| 141 | +.. code-block:: |
| 142 | +
|
| 143 | + hcitool name <mac_addr> |
| 144 | +
|
| 145 | +The command should complete with the name listed previously during the scan. Now you can pair the device as follows: |
| 146 | + |
| 147 | +.. code-block:: |
| 148 | +
|
| 149 | + rfcomm <bind_id> <mac_address> |
| 150 | +
|
| 151 | +where :code:`<bind_id>` is an arbitrary integer of your choosing. The command will create a new serial interface node |
| 152 | +with the following name: :code:`/dev/rfcomm<bind_id>`. |
| 153 | +The file acts as a regular serial device and allows you to communicate with the Shimmer. The file is also used by the |
| 154 | +library. |
0 commit comments