For some just beginning their programming journeys a common example to conquer is blinking an LED, which usually goes something like this:

digitalWrite(13, HIGH);
digitalWrite(13, LOW);

For me, I decided to try a much harder approach, in a fiddly effort that could be regarded as virtually pointless. Nevertheless, I persisted, because I thought it would be cool.

The idea: blink a Blinkt LED on Server Pi whenever it serviced a request from the outside.

For those unfamiliar with my little family of Raspberry Pi minions, here is a brief overview:

  • Server Pi – A Raspberry Pi 3 running three Node.js processes for various Pebble apps (News Headlines pin pusher, Tube Status pin pusher, unreleased notification and discovery service).
  • Backlight Pi – Another Raspberry Pi 3 with a single Node.js Express server that allows any device in the house to HTTP POST a colour to be shown behind my PC.
  • Monitor Pi – A Raspberry Pi Zero W (W, as of today) that pings the three processes running on Server Pi via the GitHub Gist discovery mechanism to give me peace of mind that they’re still up. It also checks the weather for ice and rain, and whether or not Greater Anglia have fallen over before I’ve taken the trouble of leaving for work at 7AM.

Maintaining this small fleet is a joy and a curse (one or both of “my own mini infrastructure, yay!” or  “It’s all fallen over because Node exceptions are weird, noo!”), but since I started versioning it all in Git and adding crontab and boot scripts, it’s become a lot easier. However, for this particular task, I found only one process can usefully control the Blinkt LEDs on top of Server Pi. Since this is a parameterised (services only) instance of Monitor Pi, it must be this process that does the blinking when a request is processed.

Since I’m already a big fan of modular Node.js apps, I just added another module that sets up a single-endpoint Express server, and have each of the other three Server Pi processes POST to it whenever they service a request with their own Express servers. Neat!

An hour of synchronising and testing four processes locally and on-device later, and I now have a blue blinking LED whenever a request is serviced. Sadly the activity isn’t as high as it was in the News Headlines heyday when it was tasked with converting news story images to Pebble-friendly 64 colour thumbnails and an experimental analytics service late last year, but with the interesting tentative steps the unreleased notification service is taking, Server Pi may end up seeing a bit more action than simple status checks and app news lookups in the future.

With all this work done, it’s also time for another diagrammatic mess that I like to call my infrastructure…

Update: Added changed IP facility details.

Update: Added status watchapp details.

Two of my Pebble apps push pins to the timeline to enhance their experience beyond the apps themselves:

  • News Headlines – Posts the top headline (if it’s new) every four hours. Used to push notifications and serve decoded PNG images, but that went away. Maybe someday they will return. But not for now.
  • Tube Status – Checks the TFL feed every five minutes, and pushes a pin if there is a change in the delay status. This can be a new delay, a delay that’s ended, and ‘all clear’ (no delays anymore).

Both servers also respond to GET /status to show app users if they’re up, and this has proved useful when they occasionally went down. Thanks for a ‘do node index.js forever’ loop script, this is very rarely now an issue.

Up until now, these pins were served from a $5 Digital Ocean instance which essentially spends 99.9% of its time doing absolutely nothing! After coming back to the UK and making progress towards cancelling subscriptions and emptying my US bank account, I had a better idea – use my dusty Raspberry Pi instead!

As part of my new job at EVRYTHNG, a natural avenue of exploration for getting to grips with the IoT is using a Raspberry Pi, which can run Node.js, as it turns out. Perfect! The pin servers for the two apps above use Node.js with Express.

So after a bit of code/dependency cleanup, I set up both servers on the Pi with screen and put plenty of stickers around warning against turning it off or rebooting the router.

So far, so good! What could go wrong?


The new ‘Pin Pusher’ Raspberry Pi in its native habitat – under the family computer desk.

Followup: Getting a Changed Router IP while Out the House

In the eventuality that I have to update the IP of the family router for apps to use in their status check (otherwise they think the servers have gone down, bad for users!), I used to have a Python script email me its own IP address. Sadly, Google doesn’t like this unauthenticated use of my GMail account, so I devised an alternative.

I set up my Pi as an EVRYTHNG Thng, gave it an ‘ip’ property, and wrote the following Python script to update this property in the EVRYTHNG cloud when it boots up. This way, all I have to do is ask whoever’s in to reboot the Pi, and then wait for the updated IP address! I may also make it run periodically to cover the ‘router randomly restarted’ scenario.


import requests
import socket
import fcntl
import struct
import json

user_api_key = "<key>" # Probably shouldn't publish this!
thng_id = "<id>"

def get_ip_address(ifname):
  r = requests.get("")
  spool = r.text
  start_str = "name=\"IP\" value=\""
  start_index = spool.index(start_str) + len(start_str)
  spool = spool[start_index:]
  end_index = spool.index("/>") - 1
  return spool[:end_index]

def main():
  ip = get_ip_address("eth0")
  print("IP: {}".format(ip))

  headers = {
    "Authorization": user_api_key,
    "Content-Type": "application/json",
    "Accept": "application/json"
  payload = [{
    "value": ip
  r = requests.put("{}/properties/ip".format(thng_id), headers=headers, data=json.dumps(payload))
  res = r.text


Followup: Checking Status Conveniently

Each of the two apps mentioned above have a built-in server monitoring feature in their settings screens, but that’s a lot of scrolling. To put my mind at ease I have also created a simple monitoring app that uses the same backend mechanism:


Once again, it’s been a while! The last update talked about updating apps for Chalk (Pebble Time Round), and it was around that time that I was aiming for stability on the ‘Big Three’ apps (namely Dashboard, News Headlines, and Wristponder), as well as a couple of the more popular watchfaces (namely Thin, Beam Up, Isotime, etc), so I could not be doing Pebble development all day and all night.

Happily, I eventually achieved this after a few weekend sessions, and all was good. With some interesting developments in the world of app configuration (see Clay), I added vastly improved color-selection configuration pages to those watchfaces. Color pickers beat manually entering hex strings any day of the week!

Since I’m no longer doing developer documentation/other general advocacy for Pebble (perhaps the massive Guides rewrite was my parting gift?), I have decided to try and pick it up again as a hobby, like I was doing before getting hired. I found it great fun, and very rewarding when I saw people using my apps. In general, they start life as apps I want to use my watch for, then I polish and publish them so other can find them useful.

The trouble I was running into was finding time to meet the maintenance demands of bugs/feedback from users, so now I have more time for that. Indeed, I’ve picked up a few processes/skills from my time managing my projects at Pebble that should make this process much easier. It is yet to be seen if Sheets is more efficient for a single person than JIRA, but I think I know what the answer is…


Anyway, just now I released version 3.6 of News Headlines. For some time, I’ve received the question “Can it show news from outside the UK?”. Since it started life as ‘BBC News’, that makes more sense. Yesterday I saw that the BBC has feeds for multiple regions, and so a fun exercise in adding a new feature presented itself, with a lot of potential value for users who aren’t interested in the latest scandal at Westminster.

In adding this new feature, I was reminded how complicated News Headlines is as an app, but it made the end result that much more satisfying. The process went something like this:

  • Add new enumerations for the region values.
  • Add new defaults and internal APIs for passing around the region value.
  • Add new UI items and logic to the Settings Window.
  • Add new keys for AppMessage and Persistent Storage APIs.
  • Add region-passing to the initial sync communication phase.
  • Generalise JS feed download to choose either a selected region, or a ‘category’ if the region is ‘UK’.
  • Ensure all these things played nicely for new users and also upgrading users (the latter where I’ve been stung far too many times before).
  • And as usual get massively sidetracked with refactoring and code style updates.

So now we have that. Readers around the world can make their headlines-reading experience a tad more localised if they wish. Another request I’ve been getting recently in general is to accept donations. Historically (excepting the paid version of Watch Trigger) I’ve not dabbled in donations, but since I’m not paid by Pebble anymore I will use this update to do a little experimentation. It can always be removed if nothing happens. Another experiment is making a /r/pebble subreddit post, so we’ll also see how that’s received.

After integration of the Isometric and WebSocket modules (previously ‘additional’) into PGE, I took some time to do something I’d wanted to do for a while: make it a repo usable directly after git clone. Previously the repo was an example project which could be cloned and played around with, but to use the engine in a new game required knowing which files to copy into the new project.

After re-organization, the repo can now be directly git cloned into the new project’s src directory and requires no further manipulation to be compiled. The previous asteroids example has been moved to a new pge-examples repository on the asteroids branch, which also hosts a new example ‘game’ for the WebSockets module PGE WS, which aims to allow developers to send and receive multiplayer data with as few lines as possible. The example allows each player who installs the example to trigger a vibration on all other player’s watches while they are running the game, after hosting the server.

For an overview of how to use the new WebSockets module, check out the docs for PGE WS, which summarizes how to set up the server (which forwards all data both directions automatically by default), the JS client, and a C client, which needs only to connect, send and receive data.

On May 29th, 2014 I released ‘BBC News Headlines’, an app I had used personally for a while to read BBC News stories on my wrist to keep up on current affairs with minimal effort. With the config page, I added some settings (category selection, font size, etc.) and it worked well.

When I learned about the concept behind the timeline, one of my first thoughts was “I can use this!”. I had the idea to add timeline pins to the app, as well as update it for Pebble Time to use colors, pins, as well as a new ‘cards’ design (as recommended by Pebble’s new Design and Interaction guides, which you should check out!) to replace the unnecessary menu screen. I did this, which you can read about when the app was half-way through redesign.

Now the re-design is finished, the timeline integration improved (reduced push interval, custom colors, aggressive de-duplication and status reporting to the watchapp), and config page moved into the app itself, removing a need for an external page entirely. I also added a whole bunch of polish behind the scenes, with persistent storage of the last downloaded news stories, timeout and disconnection handling, adaptive scrolling and subtle animations etc.


With a new name ‘News Headlines’, this version is now available as a straight update to ‘BBC News Headlines’ for existing and new users, and is fully compatible with Aplite (Pebble & Pebble Steel).

As a stretch goal, I have implemented all the necessary code to download the (conveniently sized 144×81) thumbnails for each news story for display in a sort of ‘viewer pane’ within the app, but discovered too late that neither the HTML5 Canvas object (which could be used to get JPEG pixel data once rendered to the object), or on-board JPEG de-compression is an option, so that feature, while exciting, will have to wait for now.

In the meantime, you can find it on the Pebble appstore!

Not a lot has been happening on this blog for the last few weeks, and the reason for that is that I have been busy beginning my internship at Pebble! It’s been a great experience so far (We released SDK 2.5 today!) and I can’t wait to work on more awesome things to help make Pebble even more useful smartwatch.

That being said, I’ve been able to find time to maintain and update my public Pebble apps at weekends, and hope to continue this pattern whenever I can, because I have some ideas I want to implement even just for myself.

A result of this is a new application of my Spark Core driven LCD project in collaboration with a new colleague to display social media trends from WhatTheTrend on animated cards on Pebble, and as an added bonus show the same information on the LCD display.

After some teething issues, it was eventually presentable and works pretty well – but for some reason only on Wi-Fi. Here’s a photo of the whole thing in action. (Eduardo Sasha is imprinted on my brain now from all the testing…)


Stay tuned for coming updates to Dashboard and Wristponder, as well as bringing Watch Trigger up to date as well!

Building on the small amount of JavaScript code developed by controlling the Spark Core pins from my Pebble, I decided to write a basic webpage to allow me to perform the same control functions but from a browser. Sure, it’s been done before, but as I have no real expertise or experience of JavaScript beyond that used for PebbleKit JS apps, and virtually none at all for HTML, it seemed like a good learning opportunity.

And it turned out to be easier than expected! After a couple of hours, the basic code was in place. The webpage looks like this:

jQUery CoreNothing too pretty to look at, but does the job well.

During the aforementioned Pebble project, I sought help with a problem in getting the same pin number back as I sent to the Spark Cloud. The solution to this turned out to be specifying the Spark.function() parameter string as a key-value dictionary, making the core (aha) code segment in this webpage as so:

//Send the request to the Core
var sendRequest = function(pin, on, device_id, access_token) {
	var url;
	if(on) {
		url = "" + device_id + "/on?access_token=" + access_token;
	} else {
		url = "" + device_id + "/off?access_token=" + access_token;

	console.log("jQuery AJAX: Requesting pin " + pin + " " + (on == true ? "on" : "off") + "...");

	//Send request using jQuert AJAX
	  type: "POST",
	  url: url,
	  data: {"args":pin},
	  success: success,
	  dataType: "json"

The entire project (three files!) can be found on GitHub here. I may expand it to include more functions in the future, but at the moment it provides a good platform to play around with, and I’ve learned a small amount about HTML forms and using jQuery. Time well spent!