For a class at UVM, we needed to create a final project with a Raspberry Pi. I was running out of ideas and time to come up with them, so I decided to settle on running LEDs off of it, but to make it not boring the LEDs would integrate with other applications. The first integration I implemented was Github.

I'll give an overview of what it looks like, and how Github activity affects the LEDs, then I'll go into more detail about how it does it later. First, here is what the LEDs look like 'idle'. When I push to a repository on github, the lights will slowly pulse to purple and back.

LEDs powered by a Raspberry Pi, attatched to a desk.

The 'idle' color can be easily changed online (again, more on this later), but green seemed to make for the coolest photo. Realistically though, It's a bit hard to do alot of work with the LEDs like this. They seem super bright in the picture, and they're just as bright in person. It can make your eyes wig out a little. I have found that having them set to a duller, warm white (pretty much like a soft white/warm light bulb) gives a really nice suble light.

There is also a web page that keeps track of all the activities that make the lights pulse. Right now, that's just github pushes. It just says the time and the number of commits that I pushed. The purple printed on the website and the purple pulsing the leds both come from the same source... so the thought is that as I want I can add more integrations to more services and they'll each have there own color.

The website itself doesn't do anything fancing. It polls the database for new activity every couple seconds and updates the screen, so no need to refresh. I don't see myself really using this at all, but it aids as a visual representation of whats happening behind the scenes. It also gives me another checkpoint when for debugging when problems come about.

Each night at 2am, all activities from the previous day are deleted, because there isn't really any point in holding on to them for longer than that.

How It Works:

Now I'll go into some more of the details about how it works. Starting out broad, and getting more specific, let's start with the general process.

Materials:

The reason I went with these materials is pretty simple. The Pi was given to me from the class (with the option to buy at the end of the semester). I'll probably end up buying it becuase honestly after doing this I don't really want to give it back. I chose to get those LEDs becuase after doing some research and watching videos, these were the only ones I could find that came with a clean power supply from the same brand, and a library on GitHub for helping to control them. After receiving them and playing around I have realized that I didn't really need to be so picky with the ones that I got. That said, the power adapter does come with a plug adapter (so no sodering), and they are some of the less expensive ones that give you control over each individual LED.

GitHub Webooks

The system is integrated with GitHub using webhooks. Repeositories on GitHub have a section where you can add new webhook endpoints, and all I do here is specify my own where I can deal with the response. At the moment only pushes are sent, but it would be very easy to add logic to deal with other things (like issues and stuff).

Once my endpoint receives the info from GitHub, it enters it into a database. The database is very simple and small. It has 2 tables... a Service table, and an Activity table.

Service Table

  • ID
  • Service Name
  • Service Color (hexidecimal)

The service color is what sets the color of the lights and the entry on the web.

Activity Table

  • ID
  • Service ID
  • Time
  • Message

When a push is sent to the endpoint, it creates a new activity with the correct message, time, and service. After getting all the info from the payload, this is all it does to create that activity: $activity = Activity::create_activity( 1, $message );

GitHubs service id is 1, so that's where the 1 comes from. The Acitivity::create_activity() method sets off a bit of a reaction, so let's get into that.

Creating an Activity, and a Pulse of Light

When an activity is created, it's entered into the database, but, the method also contains this line: Pulse::create_pulse( $service->get_color() );

It creates a pulse with the color of the service. This took a little bit of tinkering, and eventually (and probably not ideally) I ended up using the google sheets api to make it work.

Google Sheets

I have a google sheet that acts as a controller for the LEDs. There is a cell for on/off, and the idle color (hexidecimal). There is also a hidden cell for 'Pulse'. When Pulse::create_pulse( $service->get_color() ); is called, the service color is written to that hidden 'Pulse' cell.

But why?

The problem: I wanted the time delay to be next to nothing between pushing code to GitHub, and seeing the LED's pulse. This meant that The database would need to be constantly polled (like it is for the web interface). But unlike the web interface, I would also like to manually update values from the web and see them take effect in real time (such as on/off and the idle color). While these could be controls on the web interface that update values in the database, it opens up another bag of beans ensuring that I am the only person that have permission to do that. Not only does google sheets solve that problem, but their rating limiting is high enough that the sheet can be polled by the raspberry pi virtually constantly.

It's about as simple a spreadsheet as it gets. An On/Off cell, and a color cell. There is also a hidden 'Pulse' cell that is written to when an activity is created. Now, how does the Pi know actually control the LED's...

Raspberry Pi LED Control

To start, the LED controls has the heavy lifting done by this library I found on GitHub. I was using python, so it works great. I didn't really need to do much more here, but just make a few wrappers to simplify things for my needs, a configuration file for my specific LED setup, and a couple custom methods to get the effects I wanted.

As you probably figured by now, the Pi get's it's instructions from the google sheet. If it needs to be on, it goes to the color given. If off, than it shuts off. But, what if there is a pulse that was written to the hidden pulse cell? Shocker, it pulses that color. To make sure that it doesn't just repeatedly pulse that color, it removes the value from the sheet when it is done reading it. Here is what that section looks like.

if pulse != '':
	led_control.pulse_color(strip, color, pulse, 0.002, 0.25)
	values = [[status],[color],['']]
	body = {'values': values}
	result = service.spreadsheets().values().update(spreadsheetId=spreadsheetId, range=rangeName,valueInputOption='RAW', body=body).execute()

I know it's a little out of context, but heres the gist. If the hidden pulse cell isn't empty, pulse the color pulse from the color color and back. The numbers at the end are durations. Them rewrite data back to the google sheet, notably with the last index being empty (erasing the pulse cell). As I am writing this I am realizing that it is redundant to rewrite status and color to the sheet... but meh.

With the Pi nearly constantly checking the google sheet for changes, the reaction is pretty much instant. It's pretty cool to git push and then your desk glows.

Next Steps

The next thing that I'd like to do is create integration with Wunderlist. I use this as my primary checklist app, and it would be cool if it glowed red every time I checked an item off. Other cool things would be integration with my calendars, instagram, etc. The whole point is that it reacts to my online activity. GitHub was a good start and proof of concept.