Budget Blink(1)

Production blink(1) units

About a month ago I spotted Kickstarter project for a device called a Blink(1). This was a little USB device that acts like Ambient Orb and it made by the same folk that make the BlinkM 3 colour LED board that is used in them. I had loads of ideas with what to do with one.

The project had already reached it’s funding target and it had actually delivered. The devices where available to order directly from ThinkM here. I was all set to buy one except for 1 thing, the price. While I don’t really have a problem with ThinkM wanting $30 each for them, the problem is not even with the fact that HMRC will want to charge me VAT (at 20% on anything imported with a price of more than £15) on this when it is imported the real issue is that which ever courier handles the UK end of the delivery will charge me at least £8 in “handling” fee for the privileged.

Digispark and RGB Shield

I put the idea to the back of my mind for a while with the hope that the price would come down or a UK supplier would be found. While waiting I came across another Kickstarter project for a really tiny Arduino called a Digispark from the Digistump team. As well as the digispark boards themselves they where doing a range of shield, one of which was a RGB LED shield. Being a miniature arduino means I should be able to add the odd sensor or two to the board which I can use to influence the colour shown by the LED.

And to top it off I could order 2 Digisparks and 2 RGB LED shields + shipping for $26 which comes in just under the import limit for VAT.

The package was waiting for me when I got back from a weekend away and I managed to grab 5 mins today at the office to use the soldering iron to put one of the shields together and add the headers to the first digispark.

I plugged it into my laptop and the standard blink sketch seamed to be running fine. I started to follow the instructions on the wiki to set up the development environment under Linux and I think I followed it all properly but I could not get the tools to upload a new sketch to the device. I have added a comment to a similar question on the forum. In the mean time I have managed to get it all to work on my Windows machine.

EDIT: Following a comment on the forum suggesting I try plugging the digispark into a powered hub to program it I have managed to get my second digispark programmed from Linux.

Along with the RGB shield there is some sample code that makes the digispark behave as a HID device and some python code that allows you to send it RGB values to set the colour shown much the same way the Blink(1) works. When I get 5 mins I will be doing the obvious MQTT hack to allow RGB values to be posted to a topic to set the colour then look at hooking it up to some of the data feeds available.

Ingress

So there has been a bit of buzz recently (mainly about how to get a invite) about a new game from the Google NianticLabs called Ingress. It is a AR game where users do battle for one of two factions in a virtual world overlaid on top of the real world.

Ingress Logo
Ingress Logo

The game is still in closed beta at the moment and only open to people with invites, you can apply for an invite here. You can also submit Ingress inspired art work to Google Plus and tagging Brandon Badger, Brian Rose, Anne Beuttenmüller and +Joe Philley and hope they are impressed enough to let you in.

The premiss is that the work at CERN hunting for the Higgs boson has caused the release/discovery of something called Exotic Matter (XM). This XM seams to be capable of influencing human behaviour, especially in the creative and scientific direction. Following this discovery those that know of it’s existence fall in to two factions, the Enlightened who believe that XM is sent to help humanity and the Resistance who believe that XM is part of a slow insidious invasion. As well as XM there are portals which seam to be related. Portals can be captured and things called Resonators added, with these three or more portals can be linked together to create fields in the enclosed space. These field allow the Enlightened or the Resistance to try and influence the public to their way of thinking. The battle is to create the largest fields and influence the most people.

If you happen to live in an area with no portals you can add new ones to the game by sending geo-tagged photos of “interesting” locations to Google via the app, but they take between 2-3 weeks to be added. That seams a long time for somebody to maintain an interest if they are in a area with little or no existing portal, I’m still waiting for any of mine to appear, but I’ve managed to stay engaged by playing around the 4 portals up in Winchester.

There is the start of a strong social aspect to the game as well, you need to arrange for other members of your faction to coordinate attacks on portals (especially the higher level version)in order to capture them back from the opposition and you also need their help to upgrade portals to higher levels to enable longer range links.

There are plenty more detailed discussions about the game online so I won’t go on any more about that here. What is more interesting is the potential this sort of platform has. The combination of crowd sourcing and gamification may well lead to something like the game Spooks, from Charles StrossHalting State. I’m not suggesting any thing as sinister as Spooks, where the EULA turned out to be a click through copy of the Official Secrets Act, and the whole thing was being run by MI5, but it’s important to remember that Google are not running this game for fun, to start with it’s a way to get more people to volunteer more location data and also a nice way to collect a bunch of geo-tagged photos from the portal submission process. I’m already signed up to Latitude so it’s not a problem for me to send my location to google again as part of the game but I do wonder how many other players are aware of the trade they are making to play the game and what else they may need to trade as the game continues.

I’m also sure that Google have a bunch more plans for the project. Thinking about how this could be extended leads to any number of avenues, what could you do with a large enough group of people for the promise of some notional in game reward (at little to no cost to the host)? Things that come to mind:

  • Set tasks to submit photos of new buildings/locations to keep things like Streetview up to date.
  • Have users walk new roads/paths to update mapping data
  • Taking it a step further, with the right mechanisms built in to evaluate trust could you build a cheap/free delivery service having players deliver packages across a city?

These are just a few that came to mind as I was putting this post together, I’m sure there are many more. I’ll be keeping an eye on how it develops and of course capturing portals for the Resistance.

developerWorks Days Zurich 2012

This week I had a day out of the office to go to Zurich to talk at this years IBM developerWorks Days. I had 2 sessions back to back in the mobile stream, the first an introduction to Android Development and the second on MQTT.

The slots were only 35mins long (well 45mins, but we had to leave 5 mins on each end to let people move round) so there was a limit to how much detail I could go into. With this in mind I decided the best way to give people a introduction to Android Development in that amount of time was to quickly walk through writing reasonably simple application. The application had to be at least somewhat practical, but also very simple so after a little bit of thinking about I settled on an app to download the latest image from the web comic XKCD. There are a number apps on Google Play that already do this (and a lot better) but it does show a little Activity GUI design. I got through about 95% of the app live on stage and only had to copy & paste the details for the onPostExecute method to clear the progress dialog and update the image in the last minute to get it to the point I could run it in the emulator.

Here are the slides for this session

And here is the Eclipse project for the Application I created live on stage:
http://www.hardill.me.uk/XKCD-demo-android-app.zip

The MQTT pitch was a little easier to set up, there is loads of great content on MQTT.org to use as a source and of course I remembered to include the section on the MQTT enabled mouse traps and twittering ferries from Andy Stanford-Clark.

Here are the slides for the MQTT session:

For the Demo I used the Javascript d3 topic tree viewer I blogged about last week and my Raspberry Pi running a Mosquitto broker and a little script to publish the core temperature, load and uptime values. The broker was also bridged to my home broker to show the feed from my weather centre and some other sensors.

d3 MQTT topic tree visualiser

As part of writing my talks for the developerWorks Days Zurich conference next week I’ve been working on some code for the demo in the MQTT session. I was looking for a nice way to display a MQTT topic structure and the most recent value posted to topic.

In the past I have used a plugin to the freemind mindmap tool that plots the topics as and their values. This worked well but it does require a machine with Java and a very old version of freemind to make it work so it was time to see if there was another approach.

Nick O’Leary had created a neat little python MQTT to Websockets* bridge that we have been using round the office for a while and there are some really great javascript visualisation libraries out there now, so I thought I would see how hard it would be to run up a browser based version.

Starting with the d3 Collapsible Tree Layout example seamed like a good idea and it didn’t take too long to tweak it a little to make it dynamically add new topic branches when a message was received.

function addNode(topic, body) {
	var parts = topic.split("/");
	if (root.children[0]===undefined){
		var newnode = {"name": parts.shift(), "children":[]};
		root.children = [newnode];
		walk(parts,newnode,body);
	} else {
		walk(parts,root,body);
	}
	update(root);
}

function walk(parts, node, body) {
	if (parts.length != 0) {
		var current = parts.shift()
		if (node.children && node.children.length != 0) {
			var z=0;
			for(z=0; z < node.children.length; z++) {
				if (node.children[z].name == current) {
					walk(parts,node.children[z], body);
					break;
				}
			}
			if (z == node.children.length) {
				var newnode = {"name": current, "children":[]};
				node.children.push(newnode);
				walk(parts,node.children[z],body);
			}
		} else {
			var newnode = {"name": current, "children":[]};
			node.children = [newnode];
			walk(parts,node.children[0],body);
		}
	}
}

I also swapped out the where the data was loaded to use a static root rather than loading it from a json file on the server.

var root = {"name": "/","children": []};
root.x0 = h / 2;
root.y0 = 0;
update(root);

This worked pretty well so next I set about looking to see if I could add the payload of the message. To do this I added a data field to the json object for each node when populating the tree.

function walk(parts, node, body) {
	if (parts.length != 0) {
		var current = parts.shift()
		if (node.children && node.children.length != 0) {
			var z=0;
			for(z=0; z < node.children.length; z++) {
				if (node.children[z].name == current) {
					walk(parts,node.children[z], body);
					break;
				}
			}
			if (z == node.children.length) {
				var newnode = {"name": current, "children":[]};
				node.children.push(newnode);
				walk(parts,node.children[z],body);
			}
		} else {
			var newnode = {"name": current, "children":[]};
			node.children = [newnode];
			walk(parts,node.children[0],body);
		}
	} else {
		console.log("body");
		node.data = body;
	}
}

Then updated where the SVG is inserted to add a text element in the right place.

...
  nodeEnter.append("svg:text")
      .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
      .text(function(d) { return d.name; })
      .style("fill-opacity", 1e-6);
  
  // Add message payload
  nodeEnter.append("svg:text")
  	.attr("class","data")
	.attr("x", 10)
	.attr("y", 10)
	.attr("dy", ".35em")
	.text(function(d) { return d.data || ""; })
	.style("fill-opacity", 1);
  
  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
...

Again this worked very well, except that it would not update the payload value after adding the first version. I tried a number of things to get this to work, but didn’t get very far, until James Thomas pointed me at this page about how some of the internals of d3 work. It talks about entry, update and exit methods to work on new, existing and removed elements in the data. There are examples of entry and exit functions in the example so I tried adding an update method but kept getting errors that it wasn’t found. I went back and had another look at the examples in the page James had linked to and noticed that update code doesn’t actually use a functions.

...
// Add message payload
  nodeEnter.append("svg:text")
  	.attr("class","data")
	.attr("x", 10)
	.attr("y", 10)
	.attr("dy", ".35em")
	.text(function(d) { return d.data || ""; })
	.style("fill-opacity", 1);

  // Update payload if changed  
  var nodeChange = node.selectAll("text.data")
      .text(function(d) {return d.data || "";});

  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
...

An that was basically it. I’ve added a bit more code to update values when the tree branches are collapsed and to trim payloads to no more than 20 chars so the display is not too cluttered. I’m planning on improving the style sheet a little soon and possibly adding an effect so you see which payloads have been updated recently and maybe add hover text with the full payload for the shortened ones.

You can see the whole thing running here

* There is also some work being done to support Websockets with the Mosquitto MQTT broker, you can see the testing page here

Tracks2Miles 2.0

I’ve been working on a near complete re-write of Tracks2Miles over the last couple of weekends months. It’s taken so long for a couple of reasons, when the weather was good I just wanted to be outside running/cycling and for the (larger) period when it was grim out just not wanting to spend any more time writing code after doing it all day at work.

Small screen view

A number of major changes have been made, but the one that is likely to be most noticeable is the move to using Fragments for the layout of the GUI. This means that I’ve been able to create some layouts for devices. There are now 3 layouts:

  • Small size screen
  • “Normal” size screen
  • Tablet size screen

I know that a tablet layout for Tracks2Miles may seam a little strange since it started out as just a way to upload routes recorded by My Tracks and the image of a guy out jogging with a 10.1″ Galaxy tab strapped to their arm is a little stupid. But since adding the ability to view the timeline of workouts and to manually enter workouts it has started to make some more sense. That and the stats* says there are at least 31 tablet (running Android 3.1/3.2, there may be more on 4.x+) users already out there. Hopefully this new layout will pull in some more tablet users as (IMHO) looks a lot better than the phone view scaled up.

The other big change is the move to using the built in sync mechanism to drive the collection of new timeline entries. This means you can now have Tracks2Miles pull in new workouts, comments and routes on a regular basis in the background. A side effect of this is that I’m going to have to drop support for Andriod 2.1 as the syncing API had some improvements that make this a lot easier at 2.2. The same stats that showed the total number tablet users show there are only 39 users left on 2.1. The older releases should continue to work for them.

Android notification showing number of new workouts in timeline

This use of the syncing API means that I the timeline can be updated at regular intervals in the background so you will always have the latest workouts when you open the all and allows me to add alerts for when there are new entries.

A feature requested by Brian O’Donovan was the ability to sanity check speeds for different workout types, I think this mainly came about because of the distance conversion feature when the units are changed. I’ve added some options to the beta settings menu that allows you to set a min and max speed for a few of the workout types. If you enable this checking a toast message will pop up if the average speed for a workout is outside these ranges. You can access the limits under the beta section of the preferences screen.

At this point I think I’ve pretty much exhausted the capabilities of the current Dailymile API but hopefully there should be a improved version due soon. In the mean time I suppose the next step would be to look at translating Tracks2Miles to some other languages. The Google Play stats suggest that Germany might be a good first choice.

I cut what I hope to be the final beta today and after hearing back from the testers I’ll push it to Google Play as an update.

* Up until v2.0 I’ve been using the built in stats that come with the Google Play, but for this release going forward I have also included the Google Analytics library so I should get a much clearer picture of what the spread of devices running the app are.

Tracks2Miles v2.0 beta testers


Now I’m back from my amazing holiday in Yellowstone it’s time to put in a final push to get Tracks2Miles V2 out the door.

I have all the core functionality working now and I just need to finish off some of the new value add features.

So with that in mind, if you would like to beta test v2 leave a comment here and I’ll send you an email with where you can grab the apk

Man vs Horse

Today I did something a little different, instead of going to the local park to run 5km at Parkrun I set off to the New Forest to take part in a little event that Helen Bowyer had put together. The plan was to run 15km across the New Forest broken up in to 3 5km between pubs in a race against Helen on her horse Muttley. There where 7 runners from the ETS team, Me, James, Luke, Graham, Joe, Dominic and Peter also Rob on his road bike.

The runners and the Helen would be taking the same route with the runners getting a 10min head start on each leg. Rob had a route that was about twice as long and set off at the same time as Helen.

Leg 1

From The Rock at Canada Common to The Lamb at Nomansland. We set off across Canada Common from the back gate of The Rock, reasonably early on myself, James and Luke hit the front. Luckily Luke had run the route for this leg before so we didn’t have to do any looking at the map and managed to make our way to the Dealze Wood easily enough. We could probably have cut the corner a bit at the end and shaved some more time off. We had about a 5 min lead on Rob and another 3 over Helen (though she did have to detour a little to point Peter in the right direction).


View Leg 1 in a larger map

Leg 2

From The Lamb to The Royal Oak at Fritham. This was the shortest leg, but after a short climb through Bramshaw Wood it was across the open plain. The good view meant that Helen could see us and helped by the soft ground meant Muttley could go faster and caught us up with about 800m to go. Rob arrived pretty much at the same time as well.


View Leg 2 in a larger map

Leg 3

From The Royal Oak to The High Corner Inn. Jame, Luke and me hit the front again setting off, but the fact I’ve not been doing much more than 5ks recently really started to bite. I managed to stick with them both for the first half until we crossed the stream then we started to spread out. The spread ended up big enough that I lost site of Luke and James was long gone. I had a small nav failure at the bottom of the last climb up to the High Corner Inn, I think it was just my subconscious not wanting to climb, as I went past by about 400m and had to turn round and come back. Rob was first back this time.


View Leg 3 in a larger map

After we’ve finished we all went back to The Royal Oak for some lunch. It was a really good day out and I’m really up for having another go next year and maybe even have a look at the full marathon version at some point.