Technology and TerpTools

The TerpTimer is a utility under development for mobile browsers that helps sign language interpreters (and others) track teamed assignments. Given the erratic schedules and locations, I’ve also added a logger to help individuals keep track of time like a ‘personal time card.’

TerpTimer, Synchronized

A fellow interpreter suggested  to have multiple copies of TerpTimer synchronized so that team interpreters don’t have to depend on one device. Well, I have the start to this under development and I’m releasing today to the Android App Market.

To use it,  enable this feature through the App Prefs. If you don’t wish to use it, no worries — no data is transmitted unless you check the box and save the settings.  It is important to state I’m just testing this. No warranties or guaranties are implied or offered.

How it works (so far): When the application starts, it generates a pseudo-random device ID.  If TerpTimer has permission from the App preferences, it will transmit the following the count down, your device (or browser’s) time, and device ID to an application on Google’s AppEngine running an instance of OpenBD. To share the information, TerpTimer gives you a URL via a QR code. Your team interpreter can scan this code to see a webpage containing a near-synchronized countdown.

More updates are to come of course, but I wanted to release this to begin gathering information on how interpreters will use this in the field. As always comments are welcome!


I think I have the start of an invoice tracker. The user may define clients and define actions (punch in/out, arrive, depart, etc). You track  events such as “I’ve arrived at client X” and “departing location on client X”. In the end, I hope to export a CSV (comma separated file) to the sd card which later could be imported to a spread sheet.

Holy mother buzzer

So I’ve added an audible alert to when the clock hits zero. This is controlled through the application’s preferences by a check box shown to the left here.

Coding was interesting for this because I throw most settings into the Session Storage scope, which as of now only saves information as strings. I struggled a bit with this thinking I was saving a boolean variable. But I digress.

For documentation, sharing, and my own learning process, I want to show significant code bits here. The first bit occurs early on during the init process. I bind the check box to the following function. The variable sessionStorage.buzzerPermitted takes the value of the box’s checked state. An important thing to note is that sessionStorage items, at the moment, store contain strings. The this.checked returns a boolean value. So that boolean (true or false) will be converted to string value.

// Bind check box to buzzer permission
	$('#checkbox-buzzer').bind('click', function(e) {
		console.log (this.checked);
		sessionStorage.buzzerPermitted = this.checked;

The second piece follows as such. The function is called as the clock restarting either manually or by the count down reaching zero. We first check to see if the notification ability exist and if the user has set that as a preference.

var ttNotifications = {
	buzz : function () {
		if (navigator.notification && (sessionStorage.buzzerPermitted == "true")) {
		} else {
			console.log('No buzzer permitted');

Finally, I have to clean up the lexicon here. As implemented now the buzzer doesn’t fire but the preset chime does. This is a work in progress. I will have to update this shortly.

TerpTimer in the Android Market

Although, in my last post favored, I argued for the open web. I still do favor this overall; though, to stretch myself a bit, I’ve coded a version on the TerpTimer for Android using PhoneGap and released it to the market. Though I do feel like I’m cheating, it does offer some advantages. If I decide to add the full build out of TerpTools to the mix, the code is closer to the hardware.

The problem I’m looking to solve  is alerting the interpreters of an impeding session change. The interpreter in the rest/support role should not have to look down at the phone. This is just distracting during a teamed assignment. Additionally, the screen should not stay on the entire time. That eats up the battery. So I’m looking bit better hardware control for the next few versions.

Install from: AppBrain or AndroidZoom

Why “Web” App instead of “Native” App

I’m growing so tired of this debate and I’m sure in some unknown span of time, it will no longer matter. But, recently someone asked why I was targeting TerpTools as a web application instead of building a native app. I wish the answer was simple and straight forward, but as most decisions are, it’s one-part pragmatism, one-part core belief, and one-part feeling the ever increase squeeze of time in my adult life.

First, I am a web developer. I considered my first language to be Perl. As my career progressed, I added other tools to my belt as various projects and managers deemed them worthy of the task. The mobile market is fragmented and diverging. I’m still amazed at programmers who are able to design simultaneously in Java and Objective-C. Really, I hold these programmers in high respect. Their audiences are potentially huge and they can spend time catering to one segment at a time. However, my audience (free-lance sign language interpreters) are a tiny, wide-spread bunch who use various phones, on different platforms, across multiple carriers. To build something that benefits the community, I want to focus at the task in front of me. So, one code base to serve a small community is what works for me right now.

Second, any good coder should respect the user and the user’s device. Programming on the open web does this. If you want to know what I’m doing on your device, look at the source code. If you don’t want the application to track your location, instruct your browser accordingly. Browsers are (supposedly) built to limit what code can do on your device. Native apps have more control in the device and the source might be closed. Granted this argument is still open to debate and will change. And frankly, it should be debated.

The third is time. I can do more to mock-up an idea in an evening using jQuery Mobile than I can in the Android SDK. This might be different from other programmers. However, as HTML5 and the associated JavaScript API comes of age, I can do more in a shorter amount of time. And isn’t that the end goal of programming and coding. As fun as these tools and libraries are, our duty, calling, and privilege is solve a problem or simplify a task for someone else and move on to the next.

Custom Categories

I’m moving towards a more customizable interface with this application. Users may now enter their own custom categories into their logger database. Again, the logger has different benefits for different audiences. For the individual interpreter, the Logger data could easily become the beginnings of an automated invoicing system. For agencies, the combined time and geographic data from interpreters in the field might help the agency better plan future resources and account for such information vectors as travel time.

Screen to add and edit custom categories for the TerpLogger

Custom Categories shown in Logger's drop down menu

After a bit of research, I found the wonderful function which appends a new option to the original select menu and update the JQueryUI/Mobile widget.

    .append('<option value="First-New-Item-Value">First New Item Label</option>')
    .append('<option value="Second-New-Item-Value">Second New Item Label</option>')
    .selectmenu('refresh', true);

So now, code which handles the drop downs looks like this below. For speed of rendering, I only refresh the select menu once after all of the new items have been appended.

// Extend the drop down
var dropDown = {

    target: {
        selector: "UL.ui-listbox-list",
			'0' : '-1',
			'1' : '4',

   add: function(stringToAdd, parentElementPosition){
	this.clearCustom(['defaultLimit'][parentElementPosition], parentElementPosition);
        var selectItem = $(['selector'])
        var arrayToAdd = stringToAdd.split('\n');
		for (item in arrayToAdd) {
			if(arrayToAdd[item].length &gt; 0) {
					.append('' + arrayToAdd[item] + '');
		$('select').eq(parentElementPosition).selectmenu('refresh', true);


    clearCustom: function(clearAfterThisPosition, parentElementPosition){
        var selectItem = $(['selector']).eq(parseInt(parentElementPosition));
        selectItem.find('LI:gt(' + clearAfterThisPosition + ')').remove();
		$('select').eq(parentElementPosition).find('option:gt(' + clearAfterThisPosition + ')').remove();

Notes from the field

So I’m actually trying to use this application in my daily life. I am writing this from outside of my office and the gps was not on. Therefore no position was captured. The remedy was to turn on gps and refresh. I will have to add a field showing the current location and an option to manually refresh.

GeoLocation Aware

Logger passes GPS data to Google Maps

Logger passes GPS data to Google Maps

When displaying the ten most recent entries, if GPS coordinates where captured, they will be displayed as a link. If viewed from a mobile web browser, the link will render Android devices may intercept the link and prompt the user to use the native Google Maps application. Either way, you have a record of each place you checked in (logged) during the workday.