Skip to content

Commit 5678a59

Browse files
committed
Update the main README file
1 parent db7e363 commit 5678a59

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

README.rst

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,154 @@
11
pyshimmer: Unofficial Python API for Shimmer Sensor devices
22
===========================================================
33

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
518

619
.. _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.

conf/udev/10-shimmer.rules.example

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Distinguishing both Shimmer Docks and tty interfaces is somewhat difficult because the distinguishing attributes
2+
# are spread across multiple devices in the USB device tree. The main distinguishing attribute is the serial ID
3+
# of the dock. This allows to distinguish between the ECG and the PPG dock. The second step is to check if the
4+
# bInterfaceNumber of the tty device is 00 --> bootloader or 01 --> device UART.
5+
#
6+
# Unfortunately, it is not possible to check attributes from different parents in a single rule and we need to use
7+
# the Goto action to create an if clause around the bInterfaceNumber. The actual rules then check against the serial
8+
# ID to identifiy if it is the ECG or the PPG dock. Idea taken from an answer by Arnout on Stackexchange:
9+
# https://unix.stackexchange.com/questions/204829/attributes-from-various-parent-devices-in-a-udev-rule
10+
SUBSYSTEMS=="usb" ATTRS{bInterfaceNumber}!="00" GOTO="is_secondary_interface"
11+
SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor1>" ATTRS{idProduct}=="<id_product1>" ATTRS{serial}=="<id_serial1>" SYMLINK+="ttyPPGbl"
12+
SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor2>" ATTRS{idProduct}=="<id_product2>" ATTRS{serial}=="<id_serial2>" SYMLINK+="ttyECGbl"
13+
GOTO="end"
14+
15+
LABEL="is_secondary_interface"
16+
SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor1>" ATTRS{idProduct}=="<id_product1>" ATTRS{serial}=="<id_serial1>" SYMLINK+="ttyPPGdev"
17+
SUBSYSTEM=="tty" ATTRS{idVendor}=="<id_vendor2>" ATTRS{idProduct}=="<id_product2>" ATTRS{serial}=="<id_serial2>" SYMLINK+="ttyECGdev"
18+
GOTO="end"
19+
20+
LABEL="end"

0 commit comments

Comments
 (0)