One of the nice things about the holiday season is that all those colorful lights create a great opportunity to indulge in some IoT geekiness. In previous years I’ve added IoT bling to our office Christmas tree, controlled my Christmas tree lights using an Alexa voice assistant, and made an internet-connected Christmas sweater for the charity Christmas Jumper Day in the Citrix office. What could possibly be left to IoT-ify for this year’s holiday season?

The inspiration came from my colleague Steve Wilson, who came across a festive project from maker Adam Feil. Adam created a Christmas tree ornament from a Raspberry Pi and a dot matrix display to provide a countdown to Christmas Day. Steve suggested we should have one of these to count down instead to Citrix Summit and afterwards to Citrix Synergy. Of course we can Steve! And for good measure let’s make it an IoT device and create an Alexa skill to control it.

Here’s how to build your own countdown IoT Christmas tree ornament.

I loved Adam’s original device and I had a few ideas for improvements. Firstly I wanted the device to hang on the tree as a bauble. I discovered that one can buy transparent plastic baubles, which can be filled with anything that their purchaser desires. These come in a variety of sizes but not large enough for even a Pi Zero, let alone a large dot matrix display. Instead, I opted to use a smaller 128 x 32 pixel OLED display and an integrated ESP8266 development board, which includes a microcontroller programmable via the standard Arduino IDE, built-in WiFi, and a charging circuit for a small LiPo battery. At just 5.1cm long this device comfortably fits inside a 6cm bauble and leaves plenty of space for the battery as well!

To assemble the device:

  • Take one half of the bauble shell and position the ESP8266+OLED board centrally within the shell with the OLED display facing outwards, making sure that the device is horizontal with the bauble’s tie hoop at the top. Hold the board by hand or use some sticky tack to temporarily hold it.
  • Using a marker pen, put a small dot on the outside of the shell at about the point of the center of the USB socket on the ESP8266 board.

Marking the shell with a pen to show where the USB socket is positioned.

  • Remove the board and carefully drill a hole in the shell at the point marked above. This is to enable to ESP8266 to be connected to a USB cable for programming and battery charging without removing it from the bauble. The hole should be large enough for the USB plug you will be using, 10-12mm should do it. I recommend starting with a smaller drill size and working up to the required diameter.
  • Put the ESP8266 back inside the shell and line up with the drilled hole — make sure the USB plug fits. Leave the USB cable connected and hold, or use sticky tack, the board in place while using a marker again to mark on the outside of the shell where the four corners of the board touch the inside of the shell.

A hole drilled in the bauble to allow access to the ESP8266's USB socket

  • Unplug the USB cable and remove the board. Use a hot glue gun to put four small blobs of glue on the inside of the shell where the marks were made above. With the glue still molten, push the ESP8266 board into place — the four corners should sink into the four blobs of glue. Insert the USB plug through the hole to ensure it all still lines up properly. Let the glue set.
  • Perform a similar procedure on the other half of the shell to glue the battery into it. Make sure the position of the battery is such that the wires can comfortably reach the battery socket on the ESP8266 board and the battery and ESP8266 do not touch each other. I recommend letting the glue cool a little, but not fully set, before pushing the battery into the glue (if you are nervous about pushing a Lithium battery into hot glue you may want to use an alternative type of glue or fixing mechanism).
  • Plug the battery into the ESP8266 board.
  • Push both halves of the bauble shell together.

The transparent bauble with both the ESP8266 board and battery attached and a USB cable connected.

The ESP8266 does not have a real-time clock and therefore doesn’t know the current time and cannot compute the remaining time until the event to which it is counting down.

One solution would be to have the device fetch the time via the WiFi network. However, this means having to deal with the NTP protocol and handle cases where time lookups fail, and so on. Instead, my bauble never actually knows the real time: When it starts up, and every minute after that, it connects to a cloud service to find out the name of the event it should be counting down to, such as “Christmas” or “Summit,” and the number of seconds remaining from the time of this call until the event. It can then simply track the elapsed time from making this call, and subtract this from the time provided in the last call, to find the current remaining time to show on the display.

I chose to build the cloud service as an Amazon AWS Lambda function exposed to the internet via AWS API Gateway. Because of the low volume of calls, all of this fits within the free tier of these services. However, the service could be built on any platform that provides a HTTP(S) accessible endpoint and runs user-provided code to fulfill the request (Azure Functions or Cloud Functions for Firebase are two examples). All the service has to do is return a blob of JSON including the textual name of the event, and the number of seconds remaining from the current time, until that event. For example:

{"description":"Christmas","remaining":476203.913}

To create a simple Lambda function, assuming you already have an AWS account:

  • Using the AWS console create a new Lambda function using the “Author from scratch” option. Choose any name you like, choose the Node.js 8.0 runtime, select “create a new role from one or more templates” and set a role name of your choosing. You do not need to select any policy templates. Click “Create function”.

The AWS console page for creating a Lambda function

  • On the next page click on “API Gateway” from the “Add triggers” list and in the “Configure triggers” form that shows, select “Create a new API”, and set security to “Open”. Click “Add” and then “Save”.

Configuring a API gateway for the Lambda function using the AWS console.

  • The page will now show your API endpoint URL in the “API gateway” section; copy this and store it for later.
  • Click on the Lambda symbol in the graph view (it’ll have the function’s name beside it). This opens up the code editor.
  • Edit the code to be as shown below, choosing whichever event and event time that you wish.

exports.handler = async function (event) {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      "description":"Christmas",
      "remaining":(new Date("2018-12-25T00:00:00.000Z") - new Date())/1000
    })
  };
  return response;
};

  • Click “Save”
  • Using a web browser, visit the API endpoint URL you copied in step 3 above; you should get back a JSON object similar to the one shown earlier.

A more comprehensive version with a database backend, Alexa skill, support for mutliple devices, and control of an RGB LED that can be attached to the ESP8266 board, can be found at https://github.com/jamesbulpin/alexa-skill-esp8266badge

To program the device you’ll need the Arduino IDE as well as some additional hardware files for the ESP8266 board. Assuming you’re using the same board as me, follow the instructions at https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/blob/master/InstallGuide/windows.md. My summary of this procedure is this:

  • Update to latest Arduino IDE (1.8.7)
  • C:\Users\jamesbu\Documents\Arduino>mkdir hardware
  • C:\Users\jamesbu\Documents\Arduino>cd hardware
  • C:\Users\jamesbu\Documents\Arduino\hardware>git clone https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series.git heltec
  • C:\Users\jamesbu\Documents\Arduino\hardware>cd heltec\esp8266
  • C:\Users\jamesbu\Documents\Arduino\hardware\heltec\esp8266>cd tools
  • C:\Users\jamesbu\Documents\Arduino\hardware\heltec\esp8266\tools>python get.py

Then to create the sketch and program the board using the Arduino IDE:

  • Go to the “Tools” menu and select “Manage Libraries.” Search for “ArduinoJson” and install it if it’s not already installed.
  • Go to the “Tools” menu, then “Board” then click on “WiFi_Kit_8”
  • Make sure the ESP8266 board is plugged in to the computer via USB then go to the “Tools” menu, “Port” and then click on the COMx port that maps to the ESP8266 board.
  • Create a new sketch and copy in the code from https://gist.github.com/jamesbulpin/d25403d56798013fd5015db49d822826
  • Add your own WiFi SSID and key to the WiFiMulti.addAP call (search for “TODO” in the sketch)
  • Set the API_ENDPOINT value to be your API endpoint URL created above
  • Set the API_ENDPOINT_CERT_FINGERPRINT value to be the fingerprint of the API endpoint’s SSL certificate – see https://forum.arduino.cc/index.php?topic=515541.0 for details on how to do this. This is necessary because the Arduino library doesn’t know how to verify a HTTPS server’s certificate against a set of trusted authorities.
  • Save the sketch and upload to the board.
  • Hopefully the OLED display will soon start to show your countdown. If it doesn’t you can use the “Serial Monitor” from the Arduino IDE’s “Tools” menu to get the debug information sent from the sketch. This will help narrow down the problem. The most likely problem you’ll encounter is the ESP8266 board not being able to connect to your WiFi access point — in my experience this can be a problem with enterprise APs with fancy security settings.

A completed IoT bauble showing a OLED display inside a transparent bauble.

A more comprehensive version of this sketch cam be found at https://github.com/jamesbulpin/ESP8266Badge

If all of the above worked for you then you will have, as I do, a cloud-connected Christmas ornament that can count down to any event you choose. Mine is currently counting down to Citrix Summit which will be in Orlando in January; afterward, it’ll count down to Citrix Synergy in Atlanta in May. Join me at both events to see demos of some more practical, but no less fun, emerging technologies, and see how Citrix can help you securely access your workspace from a wide variety of devices, even a bauble!