Getting Started with Python Bluetooth Beta SDK

In this tutorial you'll find detailed instructions for getting started with the Python Bluetooth SDK - HMKit. The SDK can be run on openly available Raspberry Pi Zero W, Model 3B and Model 3B+ hardware boards and consists of the package hmkit. The SDK enables your application to work with vehicle data from IOT devices through short range communication (Bluetooth Low Energy).

Bluetooth Only

The Python SDK is in beta and currently works only when using Bluetooth. No production data can be accessed at the moment although testing with the emulator works well.

Introduction and Setup

Requirements

HMKit requires Python 3.7. Testing and verification has been done with Raspberry Pi Zero W. The car emulator uses Bluetooth connectivity through the Web Bluetooth initiative. At the moment it's only supported in Google Chrome on OS X, Linux and Chromebooks.

Integration

HMKit is packed as an python package. There is also a sample application, which showcase different features. The sample app can be downloaded on the Samples page or from Python BT Scaffold.

Install hmkit and setup your device

  1. Install the following dependencies:

    • libglib2.0
    • libsqlite3
    • libssl
  2. Clone the Python SDK from https://github.com/highmobility/hmkit-python

  3. Install hmkit and other libraries in your device

    ./install_libs.sh
    
  4. Disable system default Bluetooth software functions (just do once per reboot)

    ./sys_bt_off.sh
    

Create an App

In the Develop tab you will find your apps. In the app details page you are going to set the permissions it requires, manage devices and link virtual vehicles from your garage to test.

  1. Go to the Develop tab, click the big plus (+) button and select Device App. Enter a name and continue.
  2. In the left section, select the permissions that your app needs.
  3. You can edit your app name and image from the menu icon next to the app name.

Create a Vehicle

In the carmaker workspaces you will be able to create vehicles or other items to link with your app and to test with the emulators.

  1. Go to a carmaker workspace, click the big plus (+) button and select one vehicle to start. Enter a name and continue.
  2. You will find the vehicle capabilities listed to the left.
  3. If you click on the "Launch emulator" button you will see how it looks like. Next we will need to link an app with the vehicle.

Initialise the SDK

For a straight forward example of how to initialise the SDK, download the Python BT Scaffold sample app from GitHub.

  1. Once you have downloaded the SDK or sample app, go to the Apps tab, and select the app you created in the previous steps.
  2. Choose "Device certificates" from the left section and enter a name for the device.
  3. Click on the device you just created and copy the snippet from Python tab.
  4. Insert the snippet into app.py(sample app) to initialise the SDK.

Broadcasting

This section outlines how to set the app to Bluetooth broadcasting mode, making it visible to vehicles.

The main access point is the class Broadcaster, which accepts incoming connections (Links). A Link handles the authorisation(TODO expose authorisation) and different functionalities between the device and the connected vehicle.

Access to the Broadcaster is provided by the HMKit class.

Broadcaster broadcaster = HMKit.getInstance().getBroadcaster();

Once the SDK has been initialised, the Broadcaster is ready to be operated. In order to observe incoming links a listener must be set. Once this is done, broadcasting can be started.

Implement a broadcastlistener class(ie. BroadcastListener()) derived from ABC hmkit.broadcastlistener.broadcastlistener.
with functions connected(), disconnected(), state_changed(). refer abstractmethods in hmkit.broadcastlistener.broadcastlistener

# set the implemented Broadcast listener object for receiving BT broadcast events
broadcastListener = BroadcastListener()
hmkit.bluetooth.broadcaster.set_listener(broadcastListener)

# Start BLE broadcasting/advertising
hmkit.bluetooth.startBroadcasting()

# Stop BLE broadcasting/advertising
#hmkit.bluetooth.stopBroadcasting()

Observing Connections

Link events are sent to the BroadcasterListener. To observe incoming links, connected(), disconnected(), state_changed() functions should be used.

# Application code

class Broadcast_Listener(hmkit.broadcastlistener.BroadcastListener):

    def __init__(self):
        #print(" hm_app BroadcastListener(), __init__() ")
        self.bt_connected = 0;

    def connected(self, Link):
        log.info("App: Link connected")
        self.bt_connected = 1;
        # Application code after a Link has been established

    def disconnected(self, Link):
        log.info("App: Link disconnected")
        self.bt_connected = 0;

disconnected() is invoked when the Bluetooth connection is lost.

def disconnected(self, Link):
// Application code after a Link has disconnected from the device

Send a Bluetooth Command

Once the emulator is open, fire away a Bluetooth command. For example to unlock the doors of the vehicle. Note that you will get a "Vehicle Asleep" error returned if the emulator is closed.

Read more about the sdk code references in the Python SDK.

# Example: Send GetCapabilities command to vehicle through Bluetooth
# hmkit.bluetooth.link.sendcommand(constructed_bytes)

# get the command binary for GetCapabilities
constructed_bytes = get_capabilities.GetCapabilities().get_bytearray()

if constructed_bytes is not None:
    if self.hmkit.bluetooth.broadcaster.is_connected() == False:
    print("---- PY: Device is not connected through Bluetooth. Cannot send commands ----")
    return False
    else:
    # send the constructed binary to the connected vehicle
    self.hmkit.bluetooth.link.sendcommand(constructed_bytes)

Receive a Command

Incoming commands are dispatched via linklistener. The content of command corresponds to the Auto API.

The callback provides raw bytes that can be parsed with CommandResolver.resolve() in order to construct the command object. Parsing and construction of all Auto APIs commands are built into HMKit.

Read more about the sdk code references in the Python SDK.

# Example: Handle received commands from Vehicle
# Commands will be received through the registered Link_Listener() class
# Callbacks methods
class Link_Listener(hmkit.linklistener.LinkListener):

    def __init__(self):
        pass

    def command_incoming(self, link, cmdbytes):
        """
        Callback for incoming commands received from bluetooth link.
        Change in States will be received in this callback

        :param link Link: :class:`link` object
        :param bytearray cmd: data received
        :rtype: None
        """

        hmkit_inst = hmkit.get_instance()
        #hmkit_inst.autoapi_dump.message_dump(cmd)

        # resolve the received command bytes to the
        # corresponding Autoapi handler class object
        cmd_obj = CommandResolver.resolve(cmdbytes)

        if isinstance(cmd_obj, capabilities.Capabilities):
        print("Capabilities received ")

        # Example: Capability Checks
        doorlock_capability = cmd_obj.get_capability(Identifiers.DOOR_LOCKS)
        .....
        elif ____ :
        .....

Auto API

Check out the Python code reference for Auto API for further details on how to use vehicle commands.