Skip to main content

Building a Twitter Connected Stack Light Christmas Tree Topper

Using a USB controlled stack light to put on a light show and play bad renditions of popular Christmas tunes.

Christmas Tree Topper


Given the festive season is in full swing here in the office, we decided to buy a Christmas tree and decorate it with some lights. Not satisfied with not having a Christmas tree topper and having a spare Patlite USB controlled stack light, we opted to add some Twitter controlled fun to our tree.

We’ll take a look at using Tweepy to interface with the Twitter API, and how easy it is to use.

The Hardware

Hardware required for this project was minimal, comprising only a Patlite LR6-USB (200-8570) stack light, a Raspberry Pi (174-7510) and associated ancillaries to go with the Raspberry Pi.

The Hardware for Christmas Tree Topper

The chosen stack light features a set of red, amber and green LED indicators, an integrated buzzer capable of doing multiple patterns and tones, all of which is powered and controlled over USB.

As the stack light has three M4 studs protruding from the bottom for mounting, we utilised these in combination with three 20mm extrusion gusset corners to provide a method of fixing to the top of our tree.

The gusset corners then had a cable tie fed through and gently tightened down around the top of the tree. This provided a rather loose fastening to the tree, but given this was a temporary installation and the tree is somewhat fragile it sufficed.

Rather than having a bare Pi on the floor near the tree, we popped it into the case included in the kit from OKdo. A USB A-B cable was then plugged into the Pi and stack light, and that completed the hardware setup.

The Software

We decided the quickest way to interface with the stack light was using Python and the same “pyandon” module used in our Pollen Pi project. This provides an easy to use interface that requires minimal effort to get working.

Initial Setup

To get started, we wrote a fresh Raspbian image out to the Pi SD card, created the file “ssh” on the boot partition of the card and then inserted the card into the Pi — the purpose of creating a completely empty “ssh” file is that Raspbian looks for this file on first boot, and enables SSH.

This enables us to set up the Pi without ever having to plug in a monitor, keyboard and mouse.

With the Pi booted, we SSH’d into the Pi, and then installed PyAndon with pip3 install pyandon. Just as we did for the Pollen Pi project, a “udev” rule was created to allow non-root access to the stack light. To create the rule, we first created a file called 01-patlite.rules in /etc/udev/rules.d/, containing the line SUBSYSTEM=="usb", ATTR{idVendor}=="191a", ATTR{idProduct}=="8003", GROUP="pi", MODE="0666".

The “udev” system was then reloaded with the command udevadm control --reload, and the light re-plugged into the USB port on the Pi.

With the initial configuration done, we moved on to developing the code to control the stack light.

Python Application

As our Python application needed to interface with Twitter, we investigated Python modules that handled the Twitter API — eventually settling on Tweepy, one of the most widely used Twitter libraries.

Getting started with Tweepy is as easy as pip3 install tweepy, and then creating a Twitter account. With a Twitter account created, we headed into the Developer Portal and created a project, with an app called “Christmas Tree Music Bot”. In this process, a number of keys are generated which are important to store somewhere safe.

User authentication settings

With the application created, OAuth v1.0a and v2 need to be turned on — this is as easy as heading into the “User Authentication Settings” page and turning both on. Again, more keys will be generated, which need to be kept safe. As our application will be using the v2 API, a “bearer token” needs to be generated, Twitter has detailed the process here.

Pitch and frequency reference

Bearer token in hand, we started work on our application. The first thing we did was take the PyAndon example, and modify the code to utilise different tunes — this is as easy as transcribing music to fit the limited notes present in the buzzer, and adding delay notes in suitable places to make the tune sound right.

Code contains client.get_users_mentions()

With three tunes implemented, we moved on to writing the code that would interface with Twitter using Tweepy. We wanted our application to only play a tune when a user mentions the Christmas tree account with a specific tweet body — Tweepy includes a function client.get_users_mentions() that gets a user’s mentions based on user ID. This function returns the tweet ID, and the tweet body, we utilised the tweet ID to determine if a newer mention was available.

The program sits in a while loop, with a delay to avoid being rate-limited by the Twitter API interface. Another reason to add a delay is that the Twitter API enforces a limit on the amount of tweets that can be retrieved per month, and we didn’t want to hit this limit — this limit can be increased with an application to Twitter, but for our purposes, this would be fine.

Code for Christmas Tree Topper

Every time the while loop runs, the latest mentions are retrieved and the mention ID is compared to the last time the loop ran. If the tweet ID is greater, then the program checks the content of the tweet and then selects a random tune to play. After this, the buzzer is turned off and the lights are reset ready for the next run.


In this post, we’ve taken a quick look at using the Tweepy Python library to interface with Twitter and had some fun spicing up our Christmas tree.

Engineer of mechanical and electronic things by day, and a designer of rather amusing, rather terrible electric "vehicles" by night.
DesignSpark Electrical Logolinkedin