David's Blog

projects from my internship at Progress Software

Month: July, 2014

Roll Call v2: Adding Philips Hue Lights

This next project incorporates Philips Hue smart lightbulbs into my previous Roll Call project. The bulbs are set up in a row with nametags on them for the members of our office. Now, when a user enters or exits the building, their corresponding lightbulb will blink for a few seconds and change color (green for entering, red for exiting). So instead of having to open a website to check who is in the building, I can simply glance at the panel of lightbulbs. In addition, the blinking is an attention-grabbing way to notify me whenever someone enters or exits the building. Here is what the setup looks like:

Normally the lights would be red or green for each user, I turned them off for this picture since the lights were washing out everything.

Normally the lights would be red or green for each user, I turned them off for this picture since the lights were washing out everything.

Now to explain the technology that makes this possible. The Philips Hue lights communicate through Zigbee, a low-power radio transmission protocol. The lights are controlled through a central hub called the bridge, which plugs directly into a wireless router. Zigbee is a mesh network, so any signal transmitted by the bridge spreads through the lightbulb network until it reaches its target. Thus, bulbs can receive signals from the bridge even if they aren’t directly in range with it. Hue users can talk to the bridge through mobile or web apps.

Philips provides a fully-featured API for controlling the lighbulbs through the bridge, allowing you to manipulate the color, brightness, and saturation of individual lightbulbs, as well as supporting special events like color gradients or light blinking. While this API is powerful, it has the downside of requiring any application utilizing it to be on the same network as the bridge. When I started this project, I wanted to communicate directly from my Modulus-hosted Node server to the bridge, but because of the Hue architecture this isn’t possible. As an added challenge, I was working on this project at the Progress office, which has a private enterprise network with a firewall that blocks TCP connections, preventing the bridge from being controlled through external Hue servers (another feature of the product).

Thus, if I wanted to manipulate the lights from outside the network, I would need some sort of go-between that resided within the network in order to talk to the bulbs, but was also capable of spanning the firewall to communicate with external servers. I decided to use a locally-hosted instance of Node to bridge this gap. This is able to reach beyond the firewall as it relies on HTTP requests, which the firewall allows. With this decision in place, the architecture for our project looks like this:

The architecture diagram for the project.

The architecture diagram for the project.

Let’s dissect this a bit. When the user walks into the building, the iPhone in their pocket detects the Bluetooth signals transmitted from the Gimbal beacons positioned around the office. This triggers the phone to open the Beacon Receiver app in the background, which sends a POST request to the Modulus server with updated position/time data for the user. The Modulus server stores this information in a Mongo database.

While this is going on, the locally hosted Node server has been sending a GET request to the Modulus server every few seconds, asking for user location data. Each time this occurs, the Modulus server queries the database and responds to the GET request with this data. (I use the Cron package in Node to perform this repeated action). Since the database has been updated, the local server is now receiving information that differs from its local data. The server has to correct for this difference by updating the light in the Hue network corresponding to this user. It sends a PUT request to the bridge telling it to update the color and blink for a few seconds (I couldn’t do this from the Modulus server since it’s not on the same network as the bridge, hence the need for a local server). Once the bridge receives this information, it sends it back out to the Zigbee network, where it eventually reaches the lightbulb and causes its color to change.

Sounds complicated, doesn’t it? Surprisingly, the whole process only takes a few seconds. The limiting factor is how often you set the local Node server to ping the Modulus server. I’ve set the local server to ping the Modulus server every second, so it takes about a second for the lightbulbs to change. But if I pinged more frequently the response time would shrink accordingly.

I can definitely see the market for a set of lightbulbs that can easily be controlled through HTTP requests. At the scale of my project, I could’ve achieved the same result with an Arduino and a set of LEDs, but in a real household the Philips bulbs look much more presentable and their API packs a good deal of power. I was a little frustrated that I couldn’t control the bulbs from outside the network, as it seems like this should be possible with the current hardware setup given that the bridge plugs into the router itself. I get the sense that the Hue just “isn’t quite there” yet, but it certainly provides a taste of what is to come in the home automation industry. I’m looking forward to doing more projects like these as the technology gets more powerful and streamlined.

Bonus low-quality GIF of the project in action, Eduardo’s light is blinking red indicating that he has just left the building:


The Roll Call App: Integrating Beacons with Node.js and MongoDB

For this project I wanted to extend the functionality of the beacon explorer app described in my last blog post, creating something practical that could be used within the office. I decided on a “roll call” style project to see which people are in the office at any given time. With so many people here working from home or out on business trips, it’s nice to see who is actually around when trying to make lunch or meeting plans. Before I launch into explaining the project, here is a link to the website.

To build this application I needed some way of receiving and storing data from multiple devices. Node.js is well suited to this task as its non-blocking event loop makes handling multiple communications at the same time a breeze (given the current size of our office this would never really be an issue, but it makes scaling really easy if I ever wanted to use the project in a larger environment). Progress recently acquired the Node application hosting service Modulus, so I decided to give them a try for hosting the web server. Modulus has built in MongoDB support, so it made sense to use Mongo to store the information.

With my technologies in place, next I needed to figure out how to make them communicate with each other. As my Node application is an HTTP server, I need to send data to it using POST requests and respond to GET requests asking for data. The Express framework greatly simplifies all web interactions within Node, so I chose to run that on my Node server to handle all the requests from iOS and web browsers. iOS in turn can send POST requests using the NSURLSession class. For interacting with MongoDB, another Node framework called Mongoose comes in handy. Mongoose simplifies all the connecting and data organizing difficulties of working with a database. Here’s a quick diagram of the full setup:

Screen Shot 2014-07-15 at 2.38.46 PM

So what does this project actually do? All our office members have the Roll Call iOS app installed on their phones. Upon startup the app prompts for the user’s name, which is cached in the iPhone’s memory using NSUserDefaults, a class for storing simple data between user sessions. That’s the extent of user interaction with the app; it never has to be opened again. Since this app utilizes Apple’s Location Services, iOS searches for the office beacon region even when the app isn’t running. When iOS detects nearby beacons, it passively opens the app in the background for about ~10 seconds. In this time, the app sends a POST request to the Node server with 3 pieces of information: the name of the user, the timestamp of the request, and a boolean representing whether the user entered or left the building.

The request containing this information is processed by the Express framework in Node. Once the data is extracted, Node converts it into the JSON format utilized by Mongo and passes it on to the database. If this is the first database entry for a particular name, a new user is created. Otherwise, the user’s data entries are updated to reflect their latest actions. Finally, this data needs to be displayed somewhere. Modulus provides a client-facing URL for each hosted application, which I’ve populated with the MongoDB content through Node. When the user types in the project URL, it sends a GET request to the Node server, which in turn pulls the user table and action log from MongoDB and formats it with html tags for the browser. The website can be viewed here, and looks like this:

Screen Shot 2014-07-15 at 3.52.48 PM

(this data was “faked” by me walking in and out of the building a couple times, in a real application of the project I would add a password to protect privacy)

Nothing fancy, but a simple and clean way to keep track of who’s around. This project could easily be extended to a larger office by simply placing more beacons around the office. Or a warehouse manager could use it to keep track of employees within a large space, even dividing the warehouse into regions based on different beacon major and minor IDs in order to pinpoint an employee’s location within a warehouse. Software models could be run on this data to improve efficiency within the warehouse. There are many potential ways to expand this project into a full commercial product.

Finally, I just want to say that I think that the coolest aspect of this project is how the user never needs to open the iOS app for the project to function, other than at the very beginning to input their name. Apple has implemented some powerful functionality into their Core Location service, and developers can take advantage of this to implement useful and relevant location-specific projects without ever having to bother the user. I would imagine in the future that more and more apps will shy away from dependence on foreground use and instead lean towards the background monitoring + notification system used here, as it provides a simpler and more streamlined user experience.

I’ll post a Github link to the project soon.