Use Python to extend Druid on Raspberry Pi

If you’ve managed to connect to a raspberry pi through bluetooth, to talk to a builder-generated druid program (as described here) and want to get it doing something interesting, this is the page for you.

Once you’ve gotten past steps one and two, below, you can follow along with this walk-through, which demonstrates a number of cool things you can do with druid + Python on the Pi.

Step 1: Get that GUI running on the Pi

The following assumes you have a Pi setup so you can control it through bluetooth, using device druid. If not, well… do that.

Step 2: Get ready for Python

You actually have everything you need already, but to really take advantage of SerialUI‘s Python support, you want to install the pyserialui package. This is easy, thanks to pip…

On the raspberry Pi, do:

sudo pip3 install pyserialui

Horray.

Step 3: Simple shell test

On the Pi, create a file called myshell.py, and put this within:

from pyserialui.shell import SerialUIHandler

# that's it!

Now, use the “-m” switch when you launch the druid program you installed, e.g.

/usr/local/bin/myapp -m myshell.py

What you’ll see is something like this:

This is a standard REPL: a python interpreter, preloaded with a built-in SerialUI module, as well as all your inputs, commands and tracked states. You may use the standard dir(someobject) to inspect internals.

Python calls of interest at this stage, other than your friendly dir(), are:

  • self.showTree() — outputs a pretty view of the objects in the menu tree;
  • SerialUI.tree() — the actual object tree (a dict, where the keys are your command/input names and values are the objects in question;
  • SerialUI.top() — the top level menu/item container;
  • SerialUI.print() and SerialUI.println() — send text to the druid user; and
  • SerialUI.tracker() — the tracked state variables, if any.

These methods, and the objects they return, are pretty much all you need to extend druid with Python. For example, in this program I have a “Test Devices” command and a “DHCP” toggle button, under the Network sub-menu. So I can play with those:

Here, I defined a clickedMe callback and set it to be used whenever the button is clicked. I also inspected, and changed, the value of the Network -> DHCP input. Cool.

Hit CTRL+D to exit the shell, then CTRL+C to exit the program.

Step 4: Python Extension Modules

There’s basically a single requirement for any python you feed to the -m argument, when launching your program: it must include a definition for a class called SerialUIHandler.

That’s it. When you want to do anything cool, though, you’ll want to implement some methods in that class, like heartbeat() or userExit() etc, as well as make some changes to the default behaviour of your inputs and commands, or occasionally update your tracked state variables.

You may have noticed a few python files in the package sent over by the builder. In that zip file are a few things, e.g.

myproject_1.0.0_armhf.deb
MyProject/MyProject.h
MyProject/... other C++ stuff...
MyProject/python/barebones.py
MyProject/python/fulldemo.py

Copy those *.py files, in the python subdirectory, over to the Raspberry Pi.

Each of these is a functional handler module for extending your program–implementing callbacks to trigger when commands are issued, reacting to changes of inputs and such.

The barebones.py sample just uses the built-in functionality, and runs the interpreter, as above. Check the file to see how its done.

The second sample, so-called fulldemo.py, relies on pyserialui. This one implements functions using classes derived from the pyserialui wrappers, to allow you to change behaviour within instance methods.

The fulldemo will crawl the entire menu tree and create objects for all you inputs and commands. These can do their custom thing by overriding the changed() and triggered() methods, respectively.

Launch the program with

/usr/local/bin/myprogram -m /path/to/fulldemo.py

then connect with a device druid client application, while keeping an eye on the Pi terminal. You’ll see some output as you connect and play with the interface.

Going Further

Once you’ve gotten your feet wet with the samples provided, you can take a closer look at the Device Druid Python API (TODO)