Blink your Hue lights using Tableau webhooks 🚨

Control your smart lighting system with Tableau and AWS

Ayoub Briki
The Startup
7 min readApr 3, 2020

--

If you are like me; working from home until the COVID-19 situation gets better. You might want to make your office at home a little bit more exciting and increase your productivity at the same time.

How?

By using Tableau webhooks to control your smart light system!

Wouldn’t it be cool if your smart light informs you about a data source that failed to refresh on the server? Or when a workbook is deleted or published before that client or colleague sends you an email? In fact, if you are managing your company’s or your client’s Tableau Server, chances are, you already had someone at work complaining about something on the server. But unless you’re constantly checking your email or checking Tableau server to see if something happened, there is no guarantee that you can spot any activity on the fly.

Luckily, Tableau webhooks can help you overcome this situation and allow you to create endless custom workflows around events that happen on the server the moment they take place.

Since I have to work from home for the upcoming few weeks, I wanted to create something cool with my Philips Hue light system. The goal: Make my smart light inform me if a data extract is failing to refresh or if a new dashboard was published to the server.

According to Tableau, webhooks react to events that occur in Tableau. When one of the subscribed events fires, they send a POST request with a JSON payload that describes what happened to a specific URL of a receiving web service which will then trigger other events.

This sounds like a perfect job for AWS Lambda. In fact, our function will parse the payload received from the webhook and controls our smart light accordingly.

Basic setup architecture: Tableau Webhooks → AWS API Gateway → AWS Lambda → Philips Hue

Therefore, to be able to achieve this we will need the following hardware/software:

  • Tableau Server or Tableau online (version 2019.4 or higher)
  • AWS Account
  • Philips Hue light and bridge

Create the webhook

We’ll start by creating a webhook on Tableau Online (if you don’t have one yet, go ahead and join Tableau Developer Program and you’ll have access to a personal development sandbox on Tableau Online).

Sign-in

We’ll also use a new feature in Tableau 2019.4 which is Personal Access Tokens. To create one, first we need to sign in to Tableau Online then click Users->Select a user->Settings then scroll down to Personal Access Tokens and click Create new token.

Next we copy our newly created access token name and secret. Because we’ll need to place them in the following cURL post request to get an authentication token.

curl -X POST 'https://10ax.online.tableau.com/api/3.6/auth/signin' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-raw '{
"credentials": {
"site": {
"contentUrl": "<siteName>"
},
"personalAccessTokenName": "<tokenName>",
"personalAccessTokenSecret": "<tokenSecret>"
}
}'

As a response, our Tableau Online will send back the site id, a user id and a token.

Create a webhook

For this specific scenario we’ll setup a webhook for ‘data source refresh failed’ events. Tableau supports many other events that you can check here.

To create our webhook, we need to copy the site id from the previous step’s result, as well as the token. Besides that, we’ll need to create a destination url that will be explained in the next step.

curl -X POST 'https://10ax.online.tableau.com/api/3.6/sites/<site_id>/webhooks' \
-H 'X-Tableau-Auth: <token>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-raw '{
"webhook": {
"webhook-source": {
"webhook-source-event-datasource-refresh-failed": {}
},
"webhook-destination": {
"webhook-destination-http": {
"method": "POST",
"url": "<destination_url>"
}
},
"name": "ds_refresh_failed" #pick a name for the webhook
}
}'

Setup the Lambda function

In order to make our Tableau Online communicate with the Hue light API, we’ll create a Lambda function that will parse our webhook payload and will request the Hue light bulb to flash for 15 seconds 🚨. This entails that our Lambda function should also be able to communicate with the Hue Bridge: The brains of the Philips Hue smart lighting system. Let’s go through this step by step.

Create a Lambda function

There are few ways to create a Lambda function. We’ll use the AWS console and keep things as simple as possible. Once we login to our AWS account, we can search for Lambda or click Services->Lambda. Then, we click on Create function, give it a name and select our runtime (we’ll use Python 3.8) and create an execution role. The last one is mandatory since it gives our function the permission to access other AWS resources: Our API Gateway that we’ll create by adding a trigger to the newly created function and we’ll configure later on.

Add an API Gateway trigger to the Lambda function

Configure API Gateway

API Gateway will do the glue job for us; forwarding the incoming Tableau webhook requests to our Lambda function. In this case, we will only need a POST endpoint that will receive the requests and pass it through.

From the console, we select API Gateway and click on our new API. Next, we’ll create a POST method from the Actions dropdown menu and finally, we’ll configure it as follows:

  • Integration type: Lambda function
  • Lambda Region: The region of our Lambda function
  • Lambda Function: The name of our Lambda function

This way, our endpoint will forward the JSON payload received from Tableau and pass it to our Lambda function.

Deploy to a stage

Once we are done with our REST API, we must deploy it by creating a deployment and associating it with a new or existing stage. To do so, we’ll follow these steps: First go to the Actions drop-down menu, then click Deploy API. In the dialog, choose an existing entry from the Deployment stage or create a new one and provide the needed details such as Stage name and Deployment description. If everything goes well, we’ll be redirected to the stage editor page. All we have to do now is to copy the Invoke URL and use it as a destination URL in the ‘Create a webhook’ step explained above.

Build the Lambda function

Now that we have all the building blocks in place, we are ready to make our function control the Hue light system. That’s where the Hue Bridge comes into play. It offers a simple yet powerful RESTful interface that makes it developer friendly and allows us to control the light with few simple methods. If you want to learn more about how to develop for Hue you can start here.

First we’ll need to add two environment variables to our Lambda function: BRIDGE_ID and AUTH_TOKEN . The following command sets the two variables via the AWS CLI:

aws lambda update-function-configuration \--function-name <function_name> \--environment "Variables={TOKEN=<TOKEN>,BRIDGE_ID=<BRIDGE_ID>}"\--region "eu-west-1"

Please keep in mind that this is a rather hacky way to implement things, since we are not encrypting our variables and we skipped the part where we need to allow your Lambda to access and control the light from outside the local network. This is beyond our scope. For a full guide on how to secure your lambda, how to add external modules, or how to make a remote authentication to the Hue light API, feel free to check the developer guides and/or the official documentation.

Coming back to our goal, we’ll write a python script to enable our function to read the event type from the webhook and to build and send the appropriate request to the Hue API. The full code is shown below; first we’ll unpack the JSON payload, then read the received event type, next we’ll check if it’s one of three “Something went wrong” events. If that’s the case, we ask the light to perform an alert for 15 seconds with a specific color otherwise we raise an exception.

Sample python function to control Hue Light

The light should go like a siren when the event is fired. To emulate this, we’ll try to run a data source refresh task on Tableau Online without providing valid credentials and let’s see what happens 👇

The light blinks in red when the job goes from ‘Pending’ to ‘Failed’ status

VoilĂ ! The light responds to the event received from Tableau!

This is just one example; using the light to inform us about unsuccessful events on the server at the exact moment they take place. However, the Hue bulb is capable of emitting a wide range of colors. In fact, it uses a CIE color space. That’s why we defined the red color as "xy":[0.64,0.34] in our Lambda function code. The whole space is represented in the following diagram.

C.I.E color space

All points in the graph above have a unique “xy” coordinates pair that can be passed to Hue light bulb to set a color. The three Gamut triangles (A,B,C) represent the limit of the colors that the bulb is capable of producing. That being so, you can go crazy with colors and make different scenes and effects based on Tableau webhook events. What about a flashing rainbow light when someone in your company publishes a new workbook? 🎉

--

--

Ayoub Briki
The Startup

Sr. Software Engineer | Data stuff | I build things, sometimes 🏗