A coworker recently gave me a blink(1) to play with after we had spent some time discussing the merits of good hardware design. The blink(1) was kickstarted, and all of its components are open source. This means that you can modify the firmware or 3D-print a new enclosure with much less fuss than would normally be required.
Although the open source nature of the blink(1) is great, what really excites me about this technology are the new ways in which it will enable us to interact with and perceive the digital world. As we spend more time online and in front of a screen, the ways we choose to filter and translate information from the ‘virtual’ to the ‘real’ world become more important — we simply cannot process the same amount of information as a computer.
Enough Theory, How Can I Apply This?
At home I like to play around with different types of software and technology, which usually leaves me running about seven different virtual servers or applications that require constant uptime. I do not want to waste my time making sure these servers are running properly, so I thought a good first task for the blink(1) would be to have it check and make sure my servers were up. If it detects something wrong, the device will begin to glow red.
I have published all of the code and instructions for the following on Github. If you want to dive in right away over there, grab the code and go. I’ll walk through more or less the same instructions here as well. Due to some weird compilation complications I ended running my blink(1) and associated scripts from a VM where the USB dongle was passed through to the guest — so some of your mileage may vary with the scripts.
Let’s start with monitoring the status of your servers. First we will install some packages:
sudo apt-get install make git libusb-1.0-0-dev pkg-config fping
Next let’s get the blink(1) software:
git clone git://github.com/todbot/blink1.git
I’m going to assume you want my software as well, so let’s grab that:
git clone git://github.com/erfanian/blink-1-ServerStatus.git
Throughout this post I make the assumption that you are working from your home directory, so copy my software to there or modify my instructions as you go along to accommodate the change in path.
Now we have to compile the blink(1) binaries so we can access the USB dongle:
cd blink1/commandline/ && make
Copy the compiled binary to your script location:
cp ./blink1-tool ~/
Modify your udev rules so non-root users can access the device. You may need to replug the device after this step:
cd blink1/linux/ && sudo cp ./51-blink1.rules /etc/udev/rules.d/ && sudo udevadm control --reload-rules
Compile the reset program and copy it to the directory where the script will be executed. You can skip this step if you do not have issues accessing the USB device frequently on your system (be sure to exclude the reset command and function from the scripts as well):
gcc -o reset reset.c && cp ./reset ~/
Prepare the serverStatus Script
Now you should modify the server status script and place your servers in the HOSTS or HOSTS2 variable. They can be hostnames or IP addresses. Check the fping manual for more information. Make sure the script is executed in the same directory as the compiled reset binary. The HOSTS2 variable can accommodate different ports to check for your web apps.
Schedule the Script
The whole point was to automate the task, so let’s schedule the script to run without you:
Add this to the crontab to check your servers every ten minutes (be sure to use bash as the executor):
*/10 * * * * bash /home/user/serverStatus.sh
This is pretty neat, but what else can we do to bring information from the virtual world into the real one?
Hooking up the Blink(1) with the Google Analytics API to Measure your Popularity
I use Google Analytics to measure traffic on my website. Google Analytics has an API that you can use to retrieve information about your website(s). I decided to modify my Blink(1) scripts to check with the GA API to see how many visitors are on my website each day. The more visitors, the brighter the blink(1) glows. Of course, if one of my servers is down the device will continue to glow red until I correct the problem.
First I recommend you check out the Google Analytics API tutorial. The tutorial will direct you to install the API Client Library. You can build on my program by using the Reporting API Reference Guide. In order to use the supplied Python scripts with the API you need to be running Python 2.7 or lower. If you run Arch Linux, you will need to install it as Python is already at version 3:
sudo pacman -S python2
You can read more about this at the Arch Linux Python Wiki Page.
So, for example, on Arch Linux if you want to run the sample.py file with Python2.7 you have to supply the explicit path to the Python binary:
This shouldn’t be an issue on Ubuntu right now, and you can just use ‘python’ as you normally would to execute the program.
The rest of this post will assume that you have followed the installation steps above for the serverStatus script. We now need to install another program:
sudo apt-get install python-pip
Next, we can install the Google API Python Client. On Arch Linux:
sudo easy_install-2.7 --upgrade google-api-python-client
sudo easy_install --upgrade google-api-python-client
I had some trouble with SSL Cert issues using the packaged library. I didn’t feel like debugging the issue, so I have included the httplib2 library with my program to be run locally. If you want to try to debug the issue I was having, try installing these packages and go from there:
sudo pacman -S python-certifi python2-certifi sudo easy_install-2.7 certifi
Create the Necessary API Auth Files
You will need a client_secrets.json file to interface with the webservice. Follow the steps and download the necessary file using Google’s quick start tutorial. Place this file in the same directory you run the script.
If you are running these scripts on a headless server or need a graphical interface to get your auth token, you should run the script first on a machine that you prefer and scp the client_secrets.json and analytics.dat files to the headless machine.
Modify the web_popularity Script
If you get a lot of traffic on your site, you can modify this portion of the web_popularity.sh script:
#Set up the conditional statement to gauge your popularity and call the appropriate function #lowPopularity ensures that if you have any traffic you can see the light. if [ $visits_today -gt 0 ] && [ $visits_today -le 16 ]; then lowPopularity elif [ $visits_today -ge 17 ] && [ $visits_today -le 255 ]; then setPopularity $RGB elif [ $visits_today -ge 256 ]; then highPopularity else echo "I'm not sure what's going on." fi
Just set up a mathematical ratio instead of directly using $visits_today to set the $RGB value. (The max RGB value for the device is 255).
If you have more than one profile in your Google Analytics account, you will have to modify the google_analytics_popularity.py file to cumulatively add or average your visits. Right now the program just takes the first profile listed and returns today’s visits. This is the code block you want to target:
def get_first_profile_id(service): # Get a list of all Google Analytics accounts for this user accounts = service.management().accounts().list().execute() if accounts.get('items'): # Get the first Google Analytics account firstAccountId = accounts.get('items').get('id') # Get a list of all the Web Properties for the first account webproperties = service.management().webproperties().list(accountId=firstAccountId).execute() if webproperties.get('items'): # Get the first Web Property ID firstWebpropertyId = webproperties.get('items').get('id') # Get a list of all Profiles for the first Web Property of the first Account profiles = service.management().profiles().list( accountId=firstAccountId, webPropertyId=firstWebpropertyId).execute() if profiles.get('items'): # return the first Profile ID return profiles.get('items').get('id') return None
You can modify your query or explicitly set a date range or profile id here:
def get_results(service, profile_id): # Use the Analytics Service Object to query the Core Reporting API return service.data().ga().get( ids='ga:' + profile_id, #Ask only about the current day start_date= strftime("%Y-%m-%d"), end_date= strftime("%Y-%m-%d"), metrics='ga:visits').execute()
Schedule the Script
For the web_popularity + serverStatus replace the previous crontab entry with this:
*/10 * * * * bash /home/user/web_popularity.sh
The serverStatus script and the web_popularity script can be used more or less independently. They both depend on blinkFunctions to control the dongle. To use web_popularity on its own, remove the call and conditional statement around serverStatus.
I’m grateful to the Google team for their API tutorials and code on which most of my program is based.