Linking Philips Hue and Ambilight from a Raspberry Pi

RaspberryPi + AmbiLight + Hue = Happiness

Using Hue bulbs to extend the Ambilight of my TV makes me happy. Using a Raspberry Pi instead of an app for that makes me even happier.

Introduction

For some time now, I have been wondering whether there is an easier ways to link my Philips Hue smart bulbs to the Ambilight of my Philips TV. Basically, my current setup is that I need to launch the Ambilight+hue app each time I want to watch TV to establish the link. Newer Philips TVs (I think later than 2014) seem to be able to provide this functionality without relying on this app. Unfortunately, my TV is from 2013, so no luck here.

If you only care for the result / download, then skip right to the end of the article.

Looking for a Solution

My first idea was to try running the original Ambilight+hue app on a RaspberryPi somehow. After digging through Google for a while, I found out that Google provides the so-called ARC (App Runtime for Chrome) which lets you run android apps on Chrome. However, it is not supported on a RaspberryPi and there seem to be lots of compatibility issues with it, so the app probably wouldn’t run correctly. So I ditched this approach and continued looking.

After a while, I found the thread Ambilight + Hue running on Raspberry Pi where someone posted a link to a very basic prototype of a Java application which reimplemented the functionality of the Ambilight+hue app. This inspired me to create my own solution: My goal was to end up with a solution which required no interactivity on my part: It should be able to establish the link as soon as the TV is turned on and reset the bulbs after the TV is turned off.

Developing a custom solution

Reading Ambilight data

I started out by looking for more information about the API allowing to access Ambilight data. The only information I had was the URL which was used by the prototype application: http://philips-tv.home:1925/1/ambilight/measured. After some further digging, I found out that Philips TVs seem to use the so-called JointSpace protocol based on REST and JSON which someone took the time to document. With this knowledge, it was pretty straightforward to read the data from the Ambilight (I ended up using the processed Ambilight data rather than the measured data).

Updating hue bulbs

Next was controlling the Hue bulbs. I decided to go with the official Philips Hue Java SDK which is available on GitHub. Again, it took some time to find a maven repository containing the SDK. There was even an issue open at GitHub requesting Philips to provide one. Hidden inside the discussion was a link to another issue tracker where I found a link to a repository. My final entries in the pom.xml:

<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
<name>Sonatype OSSRH</name>
</repository>
<!-- ... -->
<dependency>
<groupId>com.philips.lighting</groupId>
<artifactId>huelocalsdk</artifactId>
<version>1.8.3-SNAPSHOT</version>
</dependency>

Implementation

Implementation is very simple using the following core classes:

  • AmbilightReader which is used to read from the Ambilight. It produces AmbilightData which supports arbitrary Ambilight configurations (my TV has a two-sided Ambilight, but it’s also possible to have three or four-sided ones).
  • HueController to update the color of the bulbs (identified by their name) in an easy way.
  • Ambihue which connects the two.
  • HueAmbilightMapping representing the mapping between a named hue bulb and an Ambilight position.

Ambihue uses a multi-threaded approach where one Thread is responsible for reading Ambilight data and another thread updates the Hue bulbs. The first thread is implemented using a Timer so I can set the interval for polling the Ambilight. It then uses a Semaphore to signal the second thread that data has been read which then starts to update the Hue bulbs.

Simplified: readAmbilight is called from the Timer and releases the Semaphore. Once it becomes available, the refreshHue can continue to execute (releasing the Semaphore):

private void readAmbilight() throws Exception {     
AmbilightData data = this.reader.tryReadColors();       
if (data != null) {
this.data.set(data);
this.semaphore.release();
}
}
//...
private void refreshHue() throws Exception {        
while (true) {
this.semaphore.release();
AmbilightData data = this.data.getAndSet(null);
for (Association association : associations)
association.apply(hueController, data);
}
}

Usage

ambihue is provided as a single .jar-file and can be controlled by various command line parameters. A minimal invocation might look like this (assuming Java is correctly installed and configured):

java -jar ambihue.jar -start -tvIP 192.168.178.9 -hueIP 192.168.178.17 -hueUser [username] -map Bulb1:Left1:100 -map Bulb2:Right1:100

Of course, you need to replace hueIP, hueUser and tvIP with the appropriate values and configure your own mappings.

Connecting to the hue bridge to generate a username

While hueIP and tvIP are quite straightforward, username needs some special attention. It is used to authenticate the application against the hue bridge. You can create a username with the command line option -connect. This causes the application to search for a hue bridge and prompt you to press the button to establish a connection:

java -jar amihue.jar -connect

Example output:

22:04:12.911 [main] INFO  Starting bridge search
22:04:21.596 [Thread-3] INFO  Bridges found: 1
Push button now!
Connected to hue:
IP: [...]
Username: [...]
22:04:29.918 [main] INFO  close()

Setting up mappings

Mappings are specified using the -map option. It can be specified multiple times: Once for each Hue bulb which should be mapped to an Ambilight position. The syntax is [Light Name]:[AmbilightPosition][AmbilightIndex]:[Brightness].
For example, if you want to map a bulb named “Bulb1” to the lower (1) left Ambilight with a brightness of 100 specify the following:

-map Bulb1:Left1:100

If you need help figuring out the configuration of the Ambilight of your TV, you can use the -ambilightInfo option:

java -jar amihue.jar -ambilightInfo -tvIP 192.168.178.9

Download and Source Code

Download: ambihue.jar.zip
Source code can be found at GitHub.

Issues? Let me know via the comments or create an issue on GitHub.

  • Dorv

    I think I hate you simply for having an Ambilight TV.

    • Well – that was the major point when deciding for a TV. If it helps: The things about the TV which are not Ambilight could be much better. For example, simply changing channels or switching to HDMI input can take more than 30 seconds…

      • shinmai

        Yeah, Philips TVs are great if you know what you’re getting into. They have great picture, and ambilight is awesome, but the software is an absolute mess. More than once have I had to pull the plug on the TV after it has completely frozen when using some of the SmartTV apps. Nowdays we use it mostly as a display for our Chromecast, so the only function it has is being a very good quality monitor.

        A suggestion for the mappings: an average of a number of ambilight positions mapped to one bulb. I only have one bulb in the same room with the TV and picking just one position can make the bulb act very “buzy”, but taking an average of say three positions from the top of the tv and one from each side would usually result in a nice complementary color for the bulb.