Python API?

Hi, I'm looking for a Python API for the Metawear.  Is there anything out there for Python + Metawear?

Comments

  • Currently the only officially supported API's are via Android and IOS,  so minus a version of Jython that is supported on Android (currently there doesn't appear to be one),  there is no support with this.  Another option might be to use a Rasberry Pi with a bluetooth adapter, but you would need to get deeper into the protocol etc..
  • siddrajput,

    Can you also tell us more about what you would like to do using a PythonAPI with MetaWear? Maybe there is some way we can help.
  • I'm working on an embedded platform that runs a flavor of Linux. The platform has Wi-Fi and Bluetooth. I'm writing some code in python and I'd like to be able to make the Metawear vibrate. I've been able to connect to the Metawear through the Linux command line with commands such as hcitiool and gatttool, but I don't know how to make it vibrate.
  • siddrajput,
    If you take a look at the low level Java code for the vibration motor API call, you can reverse engineer the Bluetooth packet (down to the byte) you need to send to the MetaWear board.
    Then just send the same packet using your Linux commands and voila! 
  • edited July 2015
    We're on the right track.  I've been able to read the battery level, manufacturer name, firmware version, etc., but I can't figure out the command to make the metawear vibrate.  I know I need to send a command to UUID 9001 (which has a handle of 0x1b).  See below.  But I can't figure out what that command should be.

    public enum MetaWear implements GATTCharacteristic {
        /** UUID for issuing commands to MetaWear*/
        COMMAND("9001"),
        /** UUID for receiving notifications from MetaWear i.e. reads or characteristic changes */
        NOTIFICATION_1("9006"),
        /** UUID for receiving notifications from MetaWear i.e. reads or characteristic changes */
        NOTIFICATION_2("9007"),
        /** UUID for receiving notifications from MetaWear i.e. reads or characteristic changes */
        NOTIFICATION_3("9008");

    I'm using the following commands to connect to the metawear:

    root@ubilinux:/# hcitool lescan
    LE Scan ...
    FD:B5:47:BA:20:55 MetaWear
    FD:B5:47:BA:20:55 (unknown)
    ^Croot@ubilinux:/# hcitool -i hci0 lecc --random FD:B5:47:BA:20:55
    Connection handle 64
    root@ubilinux:/# gatttool -t random -b FD:B5:47:BA:20:55 -I
    [FD:B5:47:BA:20:55][LE]> connect
    Attempting to connect to FD:B5:47:BA:20:55
    Connection successful
    [FD:B5:47:BA:20:55][LE]> char-desc
    ...
    ...
    handle: 0x001b, uuid: 326a9001-85cb-9195-d9dd-464cfbbae75a
    handle: 0x001c, uuid: 2803
    handle: 0x001d, uuid: 326a9006-85cb-9195-d9dd-464cfbbae75a
    handle: 0x001e, uuid: 2902
    Discover descriptors finished: No attribute found within the given range
    [FD:B5:47:BA:20:55][LE]>

    Handle 0x1b corresponds to UUID 9001, which according to the Android API, is " /** UUID for issuing commands to MetaWear*/".  I can send commands like so:

    [FD:B5:47:BA:20:55][LE]> char-write-req 0x1b XX XX

    But I can't figure out what to send in place of XX XX above.
  • By the way. the battery level can be read like this:

    Based on the following:

    public enum Battery implements GATTCharacteristic {
        /** Battery level, as reported from the connected device */
        BATTERY_LEVEL("19");
        
        private final UUID uuid;
        private Battery(String uuidPart) {
            this.uuid= UUID.fromString(String.format("00002a%s-0000-1000-8000-00805f9b34fb", uuidPart));
        }

    I need to read UUID 00002a19-0000-1000-8000-00805f9b34fb.  I can read it as follows:

    [FD:B5:47:BA:20:55][LE]> char-read-uuid 00002a19-0000-1000-8000-00805f9b34fb
    handle: 0x000e   value: 63

    Value 0x63 (decimal 99) means 99% charged.

  • edited July 2015
    The byte format for the haptic driver is as follows:

    0: 0x08
    1: 0x01
    2: duty cycle, between [0 - 248]
    3-4: pulse width (in ms)
    5: op frequency (0 for motor, 1 for buzzer)

    So, if you want to drive a motor for 5 seconds (5000 ms = 0x1388) at full strength (duty cycle = 248), you would send:
    0x08 - 0x01 - 0xf8- 0x88 - 0x13 - 0x00

    For buzzers, the duty cycle must always be at half strength so driving a buzzer with the same parameters would be:
    0x08 - 0x01 - 0x7f- 0x88 - 0x13 - 0x01
  • Awesome Eric, it worked.  By the way here's how I wrote the command:

    [FD:B5:47:BA:20:55][LE]> char-write-req 0x1b "0801f8881300"
    Characteristic value was written successfully

    And it vibrated for 5 seconds.  Now I can incorporate this into a Python script.
  • Hi Eric,

    Can you tell me the bytes to send to turn on the LED on the MetaWear?

    Sidd
  • siddrajput,
    Can you try to reverse engineer it form the LED function/API calls in the android code?
  • Yes, I can try to reverse engineer the Android API, but it's difficult without an Android phone. I'm developing an application on an embedded Linux platform, not an Android app.

    But I'll try again...or pickup an Android phone.

    Sidd
  • Sidd,

    I highly recommend it because it will help you debug to be able to sniff BLE packets and test with a working MetaWear API.

    Eventually we will come out with our BLE specs but it is a low priority right now.
  • edited August 2015
    The LED module is pretty straightforward, like the haptic module, in that all the code does underneath is properly place the respective parameters in a byte array.  An implementation of the Led interface is provided in the DefaultMetaWearBoard class:
    https://github.com/mbientlab/Metawear-AndroidAPI/blob/2.0.0/library/src/main/java/com/mbientlab/metawear/impl/DefaultMetaWearBoard.java#L2996

    The byte array for led commands is as follows:

    0x2 - [0x1 | 0x2 | 0x3] - {cmd parameters}

    where 0x1 = play, 0x2 = stop, and 0x3 = configure a color
  • By the way, i started porting the API to nodejs which is availabe on github in a very very early state: https://github.com/brainexe/node-metawear
    In src/registers/*.js you can take a look on a bunch of ported functionallity which might help for your python code.The next days i try to port more features.

  • Thanks brianexe.  It works great, especially the DEBUG mode.  I got the byte string I needed like this:

    noble-device  +5s send LED <Buffer 02 03 02 02 10 01 e8 03 f4 01 e8 03 c4 09 00 00 14>
    noble-device  +9ms send LED <Buffer 02 01 02>
This discussion has been closed.