Over the holiday period, Sarah and I went visiting at her mum’s in Ipswich.  Now, I’m not saying that they lack technology down there or anything, but there was no internet connection.  None whatsoever.  Zilch.  Nada.  Eeek!

What’s a techie guy meant to do in that situation?  I didn’t have a laptop or notebook with me, so I had to make do with my Android phone as the only source of technological entertainment and sole connection into the real world :-)

The Python editor may be a little small on the Android, but it means I can program on the move!Now, I’d heard about the Damon Kohler’s ASE (Android Scripting Environment) quite a while back, but never really got round to looking at it or taking it for a spin.  I’ve developed a few apps using the Android SDK, and even though Java isn’t my primary language, the whole platform has been designed to make it easy for developers to get their apps working really quickly.

However, day-to-day at Linden Lab, I work primarily in Python, so this looked like the perfect opportunity to have a delve into Python scripting use ASE, and it suited my circumstances perfectly — after all, you can type directly into the Android terminal and edit your Python scripts there and then without having to be tethered to a computer.

Installing ASE was a breeze directly from the web-site, and the supported environments were easy to install from within ASE itself — you can develop in Lua, JavaScript, Ruby, BeanShell, or Perl;  Python was my choice though, obviously.  So, following the instructions, getting started was really quick.  There are some example scripts to get you going, including a test script which quickly runs through some of the features.

And then I saw it:

import gdata.docs.service

Oooh.  Nice.  I was going to install the Google Data API Python libraries and have a play with those, and fortunately for me all the Google Data API Python modules were included in the standard ASE install.  Yay! In fact, you have everything you need to talk to all of Google’s APIs — Google Docs, Base, Blogger, Calendar, Contacts, YouTube, Webmaster Tools, Maps … they’re all there!

I was thinking of having a script that could check the stats on my web-site via Google Analytics.  I know I could have just browsed to the stats pages using Android’s built in browser, but where’s the fun in that :-)   Now I can use the Google Analytics API to directly query the stats via a Python script running on my Android.

I’ve done quite a bit of work with Google Adwords APIs, but nothing in Python, but reading through the Analytics API documentation gave enough direction.  Essentially you need to authenticate yourself with the service you’re after, then make a query against the data with the parameters you want to filter on.  Seriously, it’s that simple.

Of course, it being a small soft keyboard, it took a day and an age to type in the Python code.  Fortunately for me, I had a lot of time to kill, and this was the closest I was going to get to any kind of computing power for a few days!  Get those fat fingers typing on that diddy screen …

"""
Google Android Python Development example, using the Android Scripting Language (ASE).
This is an example of how to communicate with the Google Analytics Data API via Python.
Author: Howard Sandford, December 2009
Released under CC BY-SA-NC 3.0
"""

import gdata.analytics.service
import datetime
import android

# For use with the ASE
droid = android.Android()

# The Google Analytics account login details
USERNAME = 'your_email_account@gmail'
PASSWORD = 'your_password'

# We want data for the last 7 days
end_date = datetime.datetime.today().strftime('%Y-%m-%d')
start_date = (datetime.datetime.today() - datetime.timedelta(7)).strftime('%Y-%m-%d')

# Authenticate ourselves against the Analytics Data API
client = gdata.analytics.service.AnalyticsDataService()
client.ClientLogin(USERNAME, PASSWORD)

# Grab the data for a particular profile_id -- in this case the
# number of visits for the keywords that people have searched for us
data = client.GetData(
    ids='ga:123456',
    dimensions='ga:keyword',
    metrics='ga:visits',
    sort='-ga:visits',
    start_date=start_date,
    end_date=end_date,
)

# print out the results
total_visits = 0
analytics_results = []
for entry in data.entry:
    analytics_results.append('%s visits for %s\n' % (entry.metric[0].value, entry.dimension[0].value))
    total_visits = total_visits + int(entry.metric[0].value)

analytics_results.append('-----\n')
analytics_results.append('Total of %s visits between %s and %s\n' % (total_visits, start_date, end_date))

#droid.makeToast(''.join(visits_list))
droid.getInput('Analytics Data', ''.join(analytics_results))

Seriously, that’s how easy it is to work with the Analytics API.

The USERNAME and PASSWORD are the same as the email address and password that you would use to log into your Adwords/Analytics dashboard on the web.  And no, strangely enough, what you see in the above code is not my username/password :-)

In the code, the following snippet warrants a little more explanation:

data = client.GetData(
    ids='ga:123456',
    dimensions='ga:keyword',
    metrics='ga:visits',
    sort='-ga:visits',
    start_date=start_date,
    end_date=end_date,
)

The ids, here set to ga:123456, is the profile id(s) of the web-site(s) you want to retrieve details of (and no, ga:123456 is not my profile id either!).  Profile id is also referred to as tableId in the Google Analytics API. You can find your profile id easily enough by logging into your Adwords/Analytics account and then selecting edit on the profile.  As you can see in the screenshot below, the profile id is clearly displayed.  The profile id is a number, and you just need to add the ‘ga:’ in front of it.

Grab your profile id directly from your Google Adwords/Analytics dashboard

The dimensions parameter describes how you want your data categorised; the metrics parameter describes what details you actually want to see.  In my script, I wanted to see the number of visits to this web-site split by what keyword the visitor used to find the site.  The sort parameter above shows that I wanted the results displayed in descending order of visits, i.e. the highest number of visits first.

The start_date and end_date parameters speak for themselves.

The values for dimensions and metrics could contain more than one item, separated by commas, and the full list of available dimensions and metrics can be found in the Google Analytics Dimensions and Metrics reference.

I originally used droid.makeToast() to pop-up the results on the screen, but the pop-up didn’t stay on the screen long enough for me to read all the returned information!  The original Java implementation allows you to change the time it shows on the screen, but ASE’s makeToast() doesn’t have that parameter available.  So instead I’ve used droid.getInput() to display the Google Analytics data.

Google Analytics data via Python scripting on the Android

This method, as the name suggests, is usually used to get input from the user, however I found that using it provides a convenient way to display the data in a modal dialog, complete with OK button and scroll-bars if necessary.  ASE doesn’t yet provide any other dialog capabilities — or in Android SDK speak, intents — and no other GUI design is available.  If I were to extend this mini-app, I would prefer a more esoteric display, but if I’m going to do that it would be easier to develop the whole thing in Java from scratch … hrm, perhaps an idea for another project …

… and remember, the main reason for starting this scripting endeavour was because I didn’t have any computer available to develop on, and so Python via ASE was the perfect way to achieve my goal.

So there you have it, a simple Google Analytics Python script on the Google Android using ASE (Android Scripting Environment).  If you have questsions, just let me know!

[All files are released under Creative Commons BY-SA-NC 3.0]

The other day, well actually quite a lot of days ago, Thomas, one of my twin boys, asked about making an electronic car.  It seems that they might be making an electronic car at school soon, and he wanted to get a head start … awww, bless him, he’s only 8 :-)

So I thought I’d better get prepared.

Now, we didn’t really have much in the electronics box that we could use, apart from an L293D.  This is a DC motor driver, a simple IC that can control DC motors via an H-Bridge circuit.  Now, if we’re going to be connecting up some 5v hobby motors to a microcontroller chip such as an ATTiny45, we need to protect the chip from i) drawing too much current, and ii) problems associated with switching inductive loads such as motors.

An H-Bridge is simply a set of four switches with protective flyback diodes, and the L293D provides a very convenient way to control two motors via a microcontroller chip.  Yay!

Salvaged micro-switchesHowever, it turns out I didn’t have much else …

… apart from a USB missile launcher which hadn’t worked in years … hmmm.  Taking the USB missile launcher apart gave us some wonderful pieces to play with.  Not only did it have two low voltage DC motors, but some very useful microswitches which will come in handy later (I’m thinking of bump/collision detection here!)

So, two motors, three microswitches, ATTiny45, L293D … what else do we need?

WHEELS!

Wheel glued to the DC motorOf course.  Good job Thomas had a Konnects building set which just so happened to have some wheels included, and he was happy to donate them to the project.  It was an easy case of gluing the wheels to the DC motors.  Also, I have some standard stripboard which we can use for the chassis and to hold all the electronics.  This is looking good!

Now we have all our bits and pieces, we just need to get started on building the circuit.  The code itself is going to be simply a case of making control pins go HIGH and LOW, though for reading the microswitches I’m going to use another simple technique rather than constantly polling the input pins.

Effectively I’m going to create a resistor ladder with all the microswitches connected into the resitor ladder circuit to act as a voltage divider or potential divider, and then measure the voltage at the input pin relative to the source voltage.  By running an ADC conversion at the input pin, we can determine which microswitch has been pressed.  More on this in a later post.

So, we have all the pieces ready.  All we have to do now is build the circuit, program the ATTiny, and let Thomas take it in to his “show and tell” session at school …

… but first, perhaps, I should wait for Thomas to help me build the electronic robot car, eh? :-)   That will be the basis of the next post in this series …

Stripboard, ATTiny45, L293D, 5v DC motors, microswitches, wheels ... robot car is ready to build!

Categories