An API for My Lights


Summary

By building an API for my lights, I can hide the implementation details of the various connected lighting systems I own and make the job of controlling them—programming them—easier.

Light Bulb

A month ago, I wrote about connecting Hue and Insteon lights together so that they were both controlled by an Insteon door switch. That was good, but not good enough. The Insteon controller was controlling the Insteon lights and raising an event so that my personal cloud could control the Hue lights. But what I really need is an API for my lights. A single place where programs can control all the lights regardless of what protocol or service they use.

Before I get into the details, I see this as a key idea in the Internet of Things. Just as Novell changed the conversation around networking in the 80's by rising above protocols to talk about services (file and print), Kynetx wants to raise the IoT conversation so that we get away from individual device protocols and APIs and can talk about services. I want all my lights to turn on or off regardless of manufacturer or protocol when I flip the switch. That's what an API for my lights accomplishes.

The API is, at present, very simple. As you'd expect from me, it's event-based. There is a single event, office:lights with a single attribute state. When the event

office:lights(state=on)

is raised, I want all my lights to come on. When the event

office:lights(state=off)

is raised, I want all my lights to go off.

The Setup

If you read the earlier article, you know that I've got a Universal Devices ISY-99i that speaks Insteon. I have switches, motion detectors, outlets, and so on. I've also got four Philips Hue lights. Here's a diagram:

interop diagram for my personal cloud

I have services in my personal cloud for both the ISY-99i and the Hue hub. Those services are key because they implement the light API. The semantics of how they do that are completely encapsulated within the service. A programmer need not be concerned with how Hue and Insteon lights work. Merely raising the office:lights event will cause the service to do the right thing.

Moreover, if I add a Belkin Wemo to the mix, I just install its service in my cloud. So long as the Wemo service understands the Light API, it will work without any other part of the system being changed. A controller program (and there can be more than one) doesn't have to be configured to know about the new service because the Wemo service will quietly go about listening for the right events on the personal cloud's event bus as soon as it is installed. This is a big win over a traditional RESTful API.

Rules as Event Transformers

The rules that control lights now look like event transformers. For example this simple rule is listening for the office:door_closed event and raising an office:lights(state=off) event.

rule turn_one_off {
  select when office door_closed
  always {
    raise office event lights
        with state = "off"
  }
}

A similar rule is listening for the office:door_open event and raising an office:light(state=on) event.

Likewise the Light Controller App running in my personal cloud is controlling not only Hue lights, but the Insteon-controlled lights as well.

Light Controller Panel

Pressing the "All On" or "All Off" buttons on this screen turns all the lights on or off, not just the Hue lights. This is the functionality we need. Programmers can just turn the lights on or off without having to know anything about what lights are installed. Evented APIs support convention over configuration!

An API of Me

My personal cloud provides an API of me and my things. Installing services in my cloud customizes that API to match what I care about. Programs can take advantage of that API without knowing the implementation details of the various services or even knowing that the service exists. This kind of loose coupling provide tremendous advantage to both the developer and the owner. Personal clouds running the CloudOS make the Internet of Things usable with minimal hassle.