Skip to content
Alexander Overvoorde edited this page Aug 16, 2013 · 20 revisions

Jue is designed to be a lightweight wrapper over the actual API. It provides some convenience functions and constructs, but in general it just wraps the API calls and responses into nice classes and exceptions, so you don't have to worry about all the gory network and JSON details.

Organization

The two most important classes are HueBridge and BridgeDiscovery. The HueBridge class represents a physical Hue bridge and has methods closely resembling API calls, such as getLights() and createGroup(). The BridgeDiscovery class gives you two methods of actually finding bridges on the local network. These are useful for developing apps that automatically discover bridges.

Then there're classes representing each entity:

All of these objects contain data, like the current state (on/off, color, ...) or configuration. All these types of data have their own classes as well.

Interaction with the bridge

All operations that require interaction with the bridge go through the HueBridge class. For example, you may find code like this:

bridge.setLightName(kitchenLight, "Kitchen");

rather than:

kitchenLight.setName("Kitchen");

This is done to make it more obvious to you as developer what methods will result in requests to the bridge, and which methods are free of side-effects.

Exceptions

All functions that interact with the bridge have the checked exceptions IOException and ApiException. The former is thrown if something goes wrong on the connection/HTTP protocol level and the latter if the bridge responds with an error through the API. There is a subclass for every type of API exception that can occur. The documentation for each function tells you exactly which exceptions you can expect.

Additionally, an IllegalArgumentException may be thrown if you don't meet API restrictions when passing certain parameters. For example, name and description parameters are often limited in length. The documentation specifies the exact byte length boundaries for each function parameter. Note that with UTF-8 encoding, a single character does not always correspondent to a single byte!

Getting started

Clone the repository and add the project to your Eclipse workspace. Add it to your project's Java buildpath using the project properties.

It all begins with connecting to your bridge. Construct a new HueBridge object with the IP address of your bridge.

HueBridge myBridge = new HueBridge("192.168.1.101");

Notice that we haven't specified a username yet, so we haven't actually authenticated with the bridge. The only action available to unauthorized users is retrieving the basic configuration with only the bridge name and software version.

Config config = myBridge.getConfig();

This code doesn't work yet, because the checked exceptions IOException and ApiException need to be handled. Add a try...catch statement and try printing the name of your bridge.

try {
    HueBridge myBridge = new HueBridge("192.168.1.101");
    Config config = myBridge.getConfig();
    System.out.println(config.getName());
} catch (IOException e) {
    e.printStackTrace();
} catch (ApiException e) {
    e.printStackTrace();
}

If you're connected to the same network as your bridge and you've specified the right IP address, you should now be staring at the name of your bridge in excitement.

Authenticating

To do anything more than this, you need to authenticate with a whitelisted username on the bridge. You can do this by constructing a new bridge with the username parameter or by calling authenticate on our existing bridge object.

HueBridge myBridge = new HueBridge("192.168.1.101");
myBridge.authenticate("aValidUser");

// or

HueBridge myBridge = new HueBridge("192.168.1.101", "aValidUser");

Alternatively, you can register a new user on the bridge after pressing the link button by calling link.

If the username you specified is indeed whitelisted, the program should exit successfully, otherwise an UnauthorizedException will be thrown. Now that we've got whitelisted access to the bridge, we can get to the good stuff.

Object and FullObject

Let's start by seeing what lights are connected to the bridge by calling getLights.

for (Light light : myBridge.getLights()) {
    System.out.println(light.getName());
}

You should see something like this printed to the console:

HueLamp 1
HueLamp 2
HueLamp 3

By inspecting the Light, you will notice that it only has the two methods getId and getName. That's because the API request behind the lights retrieval only returns this much information for each light. If you want to know more about a specific light, you will have to retrieve a FullLight object.

for (Light light : myBridge.getLights()) {
    FullLight fullLight = myBridge.getLight(light);
    System.out.println(fullLight.getName() + " (" + fullLight.getState().getBrightness() + ")");
}

This class has much more information, like the model ID, software version and the current state of the light. You will see this pattern with other types of objects as well.

Light -> FullLight
Group -> FullGroup
Config -> FullConfig
Schedule -> FullSchedule

This is an advantage, because it allows you to save bandwidth when you just need to list the names of the lights or groups that you have in your app. In general, try to design your app so that it only retrieves the data it needs.

If you need to synchronise state with the bridge, it is desirable to retrieve all information in one simple request, however. This can be accomplished by retrieving a FullConfig by calling getFullConfig on the bridge. This will return all data the bridge has to offer, but it's a fairly resource intensive operation and shouldn't be used too often.

Clone this wiki locally