Creating a Smart Home

"I'm sorry Dave, I'm afraid I can't do that."

My first foray into the Internet of Things happened during a hackathon, with my friend in mechanical engineering. There's a neat little company called Robin that came as a sponsor, they do room booking with a bluetooth beacon API. If you aren't familiar with a bluetooth beacons here's what they look like:

Bluetooth Beacon

These little devices act as a center point for bluetooth. Your personal device (a phone or laptop for example) sends out a bluetooth low energy ping every few seconds and calculates things like distance from a particular point, can triangulate location down to the inches as well as act as the trigger for notifications by location. Here's what that can look like in action:

Smart Room

Building it

Starting off I made a prototype in Rails using Robin's API:

require 'json'

class RobinController < ApplicationController 
respond_to :json, :xml 

# This is included if you want to create long polling 
include ActionController::Live   
def index


# Replace $spaceid with the space ID you'd like to use, and the auth token with your auth token

excon_one = Excon.get('https://api.robinpowered.com/v1.0/spaces/$spaceid/presence', :persistent => true, :headers => {'Authorization' => 'Auth Token'})

excon_one = Excon.get('https://api.robinpowered.com/v1.0/spaces/$spaceid2/presence', :persistent => true, :headers => {'Authorization' => 'Auth Token2'})

The api is built off JSON, so setting up the requests to consume JSON was the first step. Next I defined that ActionController::Live, which allowed for long polling so it was constantly scanning for a beacon signal.

Next was the excon calls. Excon is a pretty neat library that allows for simple HTTP requests within Rails. The two requests are pulling from what are called "spaces" or their way of defining some sort of room or space within a building. Once we call the space and space ID, we can specifically ask for the current presence, which allows us to determine anyone in the room currently interfacing with the beacon. Cool!

Once the request is received we need to parse it:

# Call a JSON variable so we can parse it
@robin_json_one = excon_one.body
@robin_json_one = excon_two.body

# Actually parse the the variable from JSON into a string
@data_one = JSON.parse(@robin_json_one);
@data_two = JSON.parse(@robin_json_two);

Here we are taking the excon body variables and assigning it, so it can be parsed. Once they are set, we can use JSON.parse to parse the data into readable, serialized JSON.

Once we do that, we can finally pull out the presence from the calls with:

# Start off with first set of Data for the beacon
presence = @data_one['data']

Then we can iterate over presence and pull out specific information like such:

presence.each do |p|
if p['user']['name'] == 'Marc'
  @room = 'Kitchen'
  @optionOne = 'Food Network'
  @optionTwo = 'Recipe App'
  @optionThree = 'Mixer App'

presence = @data_two['data']

 presence.each do |p|
 if p['user']['name'] == 'Marc'
  @room = 'Living Room'
  @optionOne = 'Netflix'
  @optionTwo = 'Xbox One'
  @optionThree = 'Wii U'

We pulled out the user and their name from the array and can check if they exist within that space. For example, it could detect if I went into my living room and run whatever logic (like pulling up netflix for example).

To give you an idea of how the flow of the app works, as I walk into my kitchen, the app would pull up a menu with the button options of Food Network, Recipe App or my mixer app. I would select what I wanted, and it would pull it up for me. This gives location context to my phone or laptop wherever I am, and recommends my top actions within that location. Futuristic right?

Working with Mobile

Over the summer I revisited the idea, and decided to work on a mobile implementation of this idea. At Fidelity, I had worked with a couple MVP's using bluetooth beacons, so wanted to extend the functionality to my own house.

So using the iOS Estimote SDK I extended the functionality of what I could do within my house:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("roomCell", forIndexPath: indexPath)

    // Configure the cell...

    let major = beacons[indexPath.row].major as NSNumber!

    let minor = beacons[indexPath.row].minor as NSNumber!


    let proximity = beacons[indexPath.row].proximity
    var proximityString = String()

    switch proximity!
    {
    case .Near:
        proximityString = "Near"
    case .Immediate:
        proximityString = "Immediate"
    case .Far:
        proximityString = "Far"
    case .Unknown:
        proximityString = "Unknown"
    }

cell.textLabel?.text = "Minor: \(minor.stringValue) Proximity: \(proximityString) "

So here's one of the view functions I created within my app. Essentially bluetooth beacons are defined with a major and minor identifier. This is how the phone determines which beacon is which. Next, I define proximity, which tells me how far I am from each beacon. This is extremely useful since it can be accurate enough to tell if I'm sitting by my computer vs sitting on my couch. With this, I've extended the functionality I can do considerably.

With those defined I can set each beacon to a room with:

var beacons : [CLBeacon]!

var availableRoomsDict: [String: String] = ["11111": "Living Room",
    "12222": "Kitchen",
    "43333": "Bedroom 1",
    "35555": "Bathroom",
    "7666": "My Desk",
    "5656": "Bedroom 2"]

The numbers represent the beacon identifier. Now we can call actions based on rooms. We can do really cool things with this for example, when I don't enter my kitchen all day I have this function pull up:

func orderOut(note: NSNotification!){
    let orderOut : UIAlertView = UIAlertView(title: "Order", message: "Would you like to order out?", delegate: nil, cancelButtonTitle: "No", otherButtonTitles: "Yes")
    orderOut.show()
}

I can choose to order out, and it'll pull up Yelp, in the case I wasn't able to find the time to cook that night. Another function that I hinted at earlier is the ability to have notifications when you leave or enter a certain area. I have these set for when I leave or come back home:

func enteredTheRegion() {
    Notifications.displayWithGreeting("Welcome home buddy! Hope you had a great day today!", value: "Entered")
    if UIApplication.sharedApplication().applicationState == UIApplicationState.Background {
        self.startBackgroundTask()
    }
    self.locationManager.startRangingBeaconsInRegion(apartment)
    shouldWelcome = true    //set to false after displaying notification

}

func exitedTheRegion() {
    Notifications.displayWithGreeting("Goodbye! Work hard and have fun!", value: "Exited")
    self.locationManager.stopRangingBeaconsInRegion(apartment)
}

You can even extend these messages to get the time, and do specific actions based on time. For example, if you left your house at lets say 9PM on a weekday, usually for me, that means I need to pick up something quick like milk. It can pull up a context like "Would you like me to find the nearest grocery store?"

Overall, I've slowly started to turn my home into a context based space. I think this is the future of apps and also extremely important for design thinking. Contextualizing space is going to be one of the biggest areas of innovation within the next few years.