Hackweek 17 - hedwig

Here at SUSE it’s Hackweek again!

This year I picked two projects two work on. One of which was finishing my Raspberry Pi home surveillance.

A while ago I started writing a small XMPP bot called hedwig for this purpose.

It’s written in C using the libstrophe XMPP library. The goal is to be able to send it commands with my phone using Conversations, most importantly to take pictures of my living room. The idea happened when my former landlords started to visit my former flat uninvited :-)

The Parts

I used a Raspberry Pi 3 Model B and

I still had a power cable and card lying around. So the cost were around 75 Euro.


After booting the rpi we do the following to get hedwig:

mkdir src; cd src
git clone https://github.com/jubalh/hedwig

Hedwig works with kind of plugins. It only has 3 built in commands: !exec, !cmd and !quit. Where the first one is only available if we start it with -e switch since it allows the caller to run any command or program he wishes to. In some scenarios we might want this, in others rather not.

Everything a plugins sends to stdout will be returned by hedwig over XMPP.

Hedwig only accepts commands from people in its roster. But other than that there is no privilage handling. So make sure you use an XMPP server where you trust the admins ;-) They could manipulate your roster to include their JID and send commands to your favourite owl.

Taking pictures

I want to be able to send a simple command and get a picture of my living room. I would have to impelment XEP-0363 to do this via XMPP.

Which is something I would prefer not to do.

When you run your own server on the internet, you could just upload the picture there via scp and serve it with nginx.

I will go this route.

The pic plugin

Let’s create the directory where we place hedwigs comamands, what I call plugins:

mkdir ~/hedwig-{plugins, pictures}
vi ~/hedwig-plugins/pic

With the following content:

Run chmod u+x ~/hedwig-plugins/* to make all the plugins you create executable.


We will need an ssh key that is not password protected so the script can automatically upload the pictures we took via the first part of the script to the server.

When asked for a passphrase hit enter to leave it empty.

ssh-keygen -t rsa -b 4096 -C 'hedwig camera'
cat ~/.ssh/id_rsa_pub

Copy the public key that the last command printed out.

Shell account

We need an account on the server if we want to connect to it:

ssh headmaster@hogwarts.dumbledo.re
useradd -m hedwig
vi /home/hedwig/.ssh/authorized_keys
# paste the key we copied before
vi /etc/ssh/sshd_config
# Add: AllowUsers hedwig

This makes sure that the user on the rpi can use ssh and scp to connect as hedwig to your server, hogwarts.dumbledo.re.


In the above script we put the uploaded pictures in /srv/www/hedwig-content on our server. For this to work our user needs to have write rights for this directory: chmod hedwig /srv/www/hedwig-content. And to have the available on the web we need a webserver which serves them.

Assuming you have nginx already installed, add the following to the configuration at /etc/nginx/nginx.conf:

First start

So open up a terminal on your rpi and give it a try:

~/src/hedwig/hedwig -j hedwig@hogwarts.dumbledo.re -p oohooh -d ~/hedwig-plugins
Hedwig started!

Working directory: /home/pi/hedwig-plugins
Connecting... done

Listing roster:
	 harry@hogwarts.dumbledor.re sub=both
	 hagrid@hogwarts.dumbledor.re sub=both
End of roster

Received from harry@hogwarts.dumbledo.re/2382df20-571f-5719-5af2-54487e0df923:
hey there!


Now we want to have hedwig wake up right after we plug in our rpi.

Put the start command in a shell script, for example like this:

cat ~/hedwig-autostart.sh
/home/pi/src/hedwig/hedwig -j hedwig@hogwarts.dumbledo.re -p oohooh -d ~/hedwig-plugins

I assume we boot the rpi into graphical mode in which case we can use the normal LXDE autostart settings. An advantage is that we also see whats going on once we plug the rpi on a monitor.

Append @lxterminal -e /home/pi/hedwig-autostart.sh to ~/.config/lxsession/LXDE-pi/autostart


Let’s add one more plugin. In case we are on the road and forgot which plugins our instance of hedwig understands it would be quite useful to ask it.

For this purpose lets create ~/hedwig-plugins/list-commands with the content ls. Basically that’s all we need since this will output the content of the plugins directory and thus show us which commands are available.

Raspberry Pi Camera on my desk