Skip to content

ioLab/python-ioLabs

Repository files navigation

# Installing and Using the ioLabs Python library #

Quick answer:

* Install requirements (see below)
* Run `python setup.py install` to copy files to your `PYTHONPATH`

The library consists of:

* `ioLabs.py`
* `hid/__init__.py`
* `hid/_comming.py`
* `hid/osx.py`
* `hid/win32.py`
* `psyscopex.py`

To start using the library (once you have met the requirements listed below),
copy and `ioLabs.py`, `psyscopex.py` and the `hid` directory to somewhere on your `PYTHONPATH`.
For simplicity this can be the directory that you will be using for your project.

`ioLabs.py` is the USBBox specific code and this is what you will be using for the most part.

`hid` contains the code for the the general purpose Python HID driver and you will most likely
not need to deal with it directly - however it is used by the ioLabs module.  `hid` contains code
for OS X and Windows and will dynamically load the correct module for the OS when `hid` is imported.

`psyscopex.py` is a compatibility layer for people using PsyScopeX, as we cannot use the standard 
hid library when PsyScopeX's kernel extension is installed.

## Requirements ##

* Python 2.5+ (includes ctypes)

or

* Python 2.3.5+
* C Compiler (to compile ctypes)
* ctypes

## OS X 10.5 (Leopard) ##

Leopard ships with Python 2.5 and ctypes so no additional installation is required.

## OS X 10.4 Python 2.5 ##

1. Go to http://python.org/download/
2. Find latest version for OS X (2.5.1 at time of writing) and download .dmg
3. Open .dmg file
4. Run `MacPython.mpkg` package file
5. Enter admin password when prompted

## OS X 10.4 with Stock Python (2.3.5) ##

Need to install ctypes (requires the developer tools for a C compiler):

1. Download and install `easy_install`
 1. visit: http://peak.telecommunity.com/DevCenter/EasyInstall
 2. download: http://peak.telecommunity.com/dist/ez_setup.py
 3. run `sudo python ez_setup.py` to install
 4. if you do not have the `easy_install` command you may need to
    alter your path to include
    `/System/Library/Frameworks/Python.framework/Versions/2.3/bin`
    (where the `easy_install` script resides) or use the full path name
    when invoking e.g. 
    `/System/Library/Frameworks/Python.framework/Versions/2.3/bin/easy_install`
2. Use `easy_install` to install ctypes
 1. `sudo easy_install ctypes` (may take some time, as it has to compile everything)

## Windows XP ##

1. Go to http://python.org/download/
2. Find latest version for Windows Install Python 2.5 (2.5.1 at time of writing) and download .msi
3. Run .msi and follow installer

## Tests ##

To run unit tests for the library use `nosetests` from http://code.google.com/p/python-nose/


# USB Button Box Python API #

To get started simply import the ioLabs module and create a USBBox instance:

    from ioLabs import USBBox
    
    usbbox=USBBox()

If the physical box is not connected (or cannot be detected for some reason) an 
exception will be raised when you create this USBBox instance.

## USBBox structure ##

See the accompanying `rbox_structure` document about the high-level structure of the box.
This document specified the more object oriented API for accessing the USBBox.

## Sending Commands ##

Once you have the USBBox instance you can send commands to the USBBox.  Commands are
sent via the `commands` member variable and are named after IDs specified in the
boxes manual, only in lower case.  e.g.

    usbbox.commands.resrtc() # send RESRTC (reset realtime clock) command
    usbbox.commands.p2set(0x00) # send P2SET with value 0 (should turn on LEDs)
    usbbox.commands.dirset(1,0,0) # enable loopback mode (button presses turn on LED)

## Receiving reports ##

You can register call-back functions on the `commands` object to receive notification
about reports received from the box.  The actual reports are delivered asynchronously,
but to avoid thread safety issues they are stored on a queue until `process_received_reports`
is called.  As most events are time-stamped they can be processed as needed.

To register a call-back and have it called whenever a key is pressed one can doing something
like:

    import time
    from ioLabs import USBBox, REPORT
    # REPORT contains the report IDs
    
    usbbox=USBBox()
    def mycallback(report):
        print "got a report: %s" % report
    # register callback just for KEYDN reports
    usbbox.commands.add_callback(REPORT.KEYDN,mycallback)
    
    while True:
        usbbox.process_received_reports()
        time.sleep(0.1)

Calling `process_received_reports` in this way ensures that out call-back will be called on the
same thread as the rest of the program - avoiding any nasty surprises with asynchronous data
access.  This should also make it easier for integrating with GUI toolkits.

## Recording reports ##

Instead of registering call-backs one can instead opt to have commands sent to a file, using
the `start_recording` method on the USBBox object.  This takes a list of report IDs to record
and a file to output them to:

    import time
    from ioLabs import USBBox, REPORT

    usbbox=USBBox()
    outfile=open('output.txt')
    # record all events
    usbbox.start_recording(REPORT.ALL_IDS(),outfile)
    time.sleep(30)
    usbbox.stop_recording()
    # output.txt should now contain last 30 seconds or so events

## Miscellaneous ##

The underlying HID device for the USB Button Box is stored in `device` on the USBBox instance.
It can be accessed to manually send commands to the device using it's `set_report(report_data)`
command - simply passing a string of the bytes that should be sent in the report.