This is a mirror of a github project page. The actual project, complete with clone URLs, issue tracking, etc, is hosted here
Zoo      About | Inventory | Bootstrap | Workflows | Notes |
Automation and CM for the Zoo that is my random hardware collection and all the infrastructure experiments running on it. Amongst other things, the collection includes lots of raspberry pi's, a few sensors and a few actuators, a synology NAS, a OpenWRT-flashed hootoo tripmate AP and a beefier desktop for experimenting with hungrier infrastructure like Kubernetes, Spark, and Hadoop.


This is an experimental environment where nothing is guaranteed to be particularly smart or stable. You have been warned: this repo will always be a work in progress. The assumption here is that things are happening inside an isolated network (my LAN) and there are lots of default accounts left in place, etc etc.

That said, there are lots of useful patterns in this project if you're interested in doing things like experimenting with networks, creating a media center with your raspberry pi, experimenting with offline speech recognition / digital assistants, and controlling devices in the real world.


For a up-to-date hardware inventory, you can view the manifest, which includes hardware descriptions and purchase and spec URLs.

As an infrastructure inventory, what follows is a list of some of the more stable stuff I'm playing with. You can find corresponding playbooks for provisioning the infrastructure as well as command-and-control scripts in the ansible folder.

  • Kodi (Open source media center suitable for smart TVs, etc)
  • InfluxDB (time series DB)
  • Statsd/Graphite/CollectD/Grafana stack (metrics collection and reporting for real, containerized, or virtual hosts)
  • Jenkins (classic CI/CD)
  • Gitlab (VCS and containerized CI/CD)
  • DNSMasq (Lightweight, easy to update DNS for the whole LAN)
  • Cabot (Monitoring and alerts for hosts and Jenkins jobs)


You need a python stack. To install requirements for both ansible galaxy roles and python, use make requirements. It's recommended to do all development inside a python virtualenv! Just install and activate one before you run the make command above


Run playbook "playbook" against host "hostname": * Run fab host:"host_name" run:"playbook_name"

SSH to host with standard keypair: * Run fab host:"host_name" ssh

Updating DNS things: * Rebuild DNS service to include all (and only) hosts/aliases in manifest with fab dns * Set a host to use lab DNS by default fab host:foo run:lab-dns * Run fab hosts to update local /etc/hosts and ~/.ssh/config. (Interactive; Be prepared to answer login password prompt at console.)

Adding a host: * Decide hostname and static IP for hardware * Add description, initial username, and static IP to the manifest. * Use the Update DNS Workflow to configure /etc/hosts, ssh config, and DNS. * Run fab host:hostname bootstrap to install laboratory standard ssh keys * Begin writing a playbook to provision the host * Consider adding a health check to Cabot.

Bootstrap CI/CD: * placeholder * placeholder


This section is for saving various temporary notes about builds and experiments in progress



from xbmcjson import XBMC, PLAYER_VIDEO
xbmc = XBMC("http://kodi/jsonrpc", 'guest', 'guest')
print xbmc.JSONRPC.Ping()

# Navigate throught windows
# xbmc.GUI.ActivateWindow({"window":"home"})
# xbmc.GUI.ActivateWindow({"window":"weather"})

# Show some notifiations :
# xbmc.GUI.ShowNotification({"title":"Title", "message":"Hello notif"})

# ...and so on
xbmc.GUI.ShowNotification(title="Title", message="Hello notif")

# Library interaction :
# xbmc.VideoLibrary.Scan()

Offline Speech Recognition

Bootstrap For OSX:

brew install PortAudio
pip3 install pyaudio --global-option="build_ext" --global-option="-I/usr/local/include" --global-option="-L/usr/local/lib"
pip3 install SpeechRecognition
brew install swig
pip3 install pocketsphinx

Bootstrap for Debian/Ubuntu:


USB Power Control

OpenWRT on hootoo


Certain files are encrypted by ansible-vault as part of normal deployment automation.

You will need a file called .vault_password which contains the master key. I will never give it to you.

Developers should add the pre-commit hook, which ensures unencrypted files are never committed to version control. From the project root, run these commands:

$ chmod ugo+x scripts/
$ ln -s -f ../../scripts/ .git/hooks/pre-commit

(The path in the link above might look weird.. that's because when git is evaluating the symlink, it does so using .git/hooks as its working directory.)

You can view and change the list of protected files by editing scripts/

When the hook prevents you from committing, it will give instructions for encrypting files. Example output follows:

ERROR: Refusing to commit!

Found these protected files which are unencrypted:

Running these commands to encrypt them:

  fab encrypt:"foo/bar"
  fab encrypt:"baz"

You can try your commit again now.

To encrypt/decrypt files manually use helpers provided by the fabfile, i.e. fab encrypt:FILE_PATH and fab decrypt:FILE_PATH respectively. Again, if you want a certain file protected from accidental unencrypted commits.. you must edit the commit hook

If you ever actually commit secrets by accident to version control, fix it immediately before letting history obscure things. Here is a github recommended tool for fixing things.