Author: Praveen Sundar
In this blog, I will bring about the design details on how MuleSoft can be used as a platform for integrating IoT devices at very elementary level to begin with. Using MuleSoft as integration platform provides below benefits:
Seamless connectivity: Connect and orchestrate data on IoT devices or with back-end applications using APIs.
Speed of delivery: Use open standards, developer-friendly tools, and prebuilt transport protocols, such as Zigbee and MQTT, to integrate IoT devices quickly.
Future-proof your IoT integrations: Create a flexible IoT architecture and deploy anywhere — on-premises, in the cloud, or in a hybrid environment
INTRODUCTION
For our implementation, let’s use Philips Hue Smart Light as IoT device & use Remote APIs, for example: https://api.meethue.com/bridge/<whitelist_identifier>/lights in order to get a list of all lights that have been discovered by the bridge, provided by Philips Hue in order to communicate with the device.
Firstly, let me brief about the approach used:
- Set up the Hue Bridge for the Smart Light (Follow the User Manual & make sure to create a Hue Account in order to control the device via installed App).
- Get the Access Token for OAuth2
Authentication, either Basic or Digest. - Get the <whitelist_identifier> for identification.
- In Anypoint Studio or Design Center, design a mule flow to have the required Remote APIs invoked.
- Deploy the application in the cloud using Runtime Manager.
Various APIs provided:
- GET /bridge/<whitelist_identifier>/lights: Gets a list of all lights that have been discovered by the bridge.
- GET /bridge/<whitelist_identifier>/lights/new: Gets a list of lights that were discovered the last time a search for new lights was performed. The list of new lights is always deleted when a new search is started.
- POST /bridge/<whitelist_identifier>/lights: Starts searching for new lights.
- GET /bridge/<whitelist_identifier>/lights/<id>: Gets the attributes and state of a given light.
- PUT /bridge/<whitelist_identifier>/lights/<id>: Used to rename lights. A light can have its name changed when in any state, including when it is unreachable or off.
- PUT /bridge/<whitelist_identifier>/lights/<id>/state: Allows the user to turn the light on and off, modify the hue and effects.
- DELETE /bridge/<whitelist_identifier>/lights/<id>: Deletes a light from the bridge.
For more info on the above APIs, please refer https://developers.meethue.com/develop/hue-api/lights-api/
DESIGN APPROACH
The very first part of the approach is to generate Access Token for OAuth2 Basic Authentication & Whitelist Identifier for device identification in order to invoke above APIs.
Steps involved:
- Register to Hue Developers account (https://developers.meethue.com/register/) & login.
- Generate clientid and clientsecret for your Mule application to be developed by navigating to ‘Remote Hue API appids’ under your profile. Enter mandatory fields such as ‘App name’, ‘Callback URL’ & ‘Application description’. Then Select ‘I Agree’ & click on ‘Submit’.
- Hit this URL: https://api.meethue.com/oauth2/auth along with the required query parameters in any browser. Complete GET HTTP request should be:
https://api.meethue.com/oauth2/auth?clientid= q9TCFeNZAlwbOJiWsxUCiILDipMeSeJf&appid=ecb5fafffe00d034&deviceid=huesmartlightintegrate&state=xUvdhs&response_type=code
where
clientid: The one generated in the previous step.
appid: ID generated once Hue Account for the device is created.
deviceid: The one generated in the previous step.
state: Use same as given above.
response_type: Use ‘code’ as value.
- On hitting this URL, you are taken to Grant permission page of Hue Account:
Click on ‘Yes’ in order to grant permission, which in turn takes you to the Callback URL you gave in the Step #2. See below:
http://localhost:8081/huesmartlight?code=2OOd5ZMY&state=xUvdhs where code is the authorization code.
- There are two types authorization headers possible for getting an access_token: Hue Remote API supports Digest and Basic authentication methods. We recommend using Digest for your applications, as with this method you will be able to handle your credentials in a more secure way.
Digest Authentication
- Submit this POST HTTP Request without Authorization header, which is called Requesting Challenge:
where
code: The one generated in the previous step.
grant_type: Use ‘authorization_code’ as value.
This results in a response with the header ‘WWW-Authenticate’ as below:
Digest realm=”oauth2_client@api.meethue.com”, nonce=”4583f111848efc8f350b2e237ed06835″
With this nonce, you now have all information you need to build a Digest header to accompany your token request. The Digest header contains a response parameter that only your applications can build.
- Now, submit this POST HTTP Request along with a Digest authorization HTTP header:
Digest header as:
Authorization : Digest username=”n77xrZFmxui3jCIMNpbih2yOIAGHDwdK”,realm=”oauth2_client@api.meethue.com”,nonce=”4583f111848efc8f350b2e237ed06835″,uri=”/oauth2/token”,response=”753b344b680903d97dee6563d46237ee”
where
username: clientid which you have received from Hue when registering for the Hue Remote API (see previous steps).
realm: Same as given above.
nonce: The value you got from the challenge.
uri: Same as given above.
response: This is unique for every token request and must be calculated.
The response parameter is calculated from a set of MD5 hashed string concatenations. The response is calculated as follows:
PParameter | Value |
HASH1 | MD5(“CLIENTID” + “:” + “REALM” + “:” + “CLIENTSECRET”) |
HASH2 | MD5(“VERB” + “:” + “PATH”) |
response | MD5(HASH1 + “:” + “NONCE” + “:” + HASH2) |
where
CLIENTID: The clientid you have received from Hue when registering for the Hue Remote API.
REALM: The realm provided in the challenge “401 Unauthorized” response (i.e. “oauth2_client@api.meethue.com”).
CLIENTSECRET: The clientsecret you have received from Hue when registering for the Hue Remote API.
VERB: The HTTPS verb you are using to request the token (i.e. “POST”).
PATH: The path you are making your request to (i.e. “/oauth2/token”).
NONCE: The nonce provided in the challenge “401 Unauthorized” response.
In pseudo code, this would translate into the following:
var HASH1 = MD5(“n77xrZFmxui3jCIMNpbih2yOIAGHDwdK:oauth2_client@api.meethue.com:q5MEfUxEO4GQgFSE”) = eb94d24d533068011dbd883f8274b692;
var HASH2 = MD5(“POST:/oauth2/token”) = 8b5c4d23fb4deb8c96a72c04ee3de14a;
var response = MD5(“eb94d24d533068011dbd883f8274b692:4583f111848efc8f350b2e237ed06835:8b5c4d23fb4deb8c96a72c04ee3de14a”) = 753b344b680903d97dee6563d46237ee;
On submitting this POST request, a response is generated, see below for how the response looks:
< HTTPS/1.1 200 OK
< Content-Type: application/json
{
“access_token”:”VAJc2G6SHQxLQN5qtAeohG7yUbTn”,
“access_token_expires_in”:”604799″,
“refresh_token”:”4k7uu0QTYBunlHlOgWLydNFnKl7z6gnD”,
“refresh_token_expires_in”:”9676799″,
“token_type”:”BearerToken”
}
Basic Authentication
Submit this POST HTTP Request along with a Basic authorization HTTP header that includes your base64 encoded clientid and clientsecret: https://api.meethue.com/oauth2/token?code=2OOd5ZMY&grant_type=authorization_code
where
code: The one generated in the previous step.
grant_type: Use ‘authorization_code’ as value.
In order to obtain an access_token with Basic Authentication this header is required:
Authorization: Basic <base64(clientid:clientsecret)>
where clientid & clientsecret are those which you have received from Hue when registering for the Hue Remote API (see previous steps).
On submitting, a response is generated, see below for how the response looks:
< HTTPS/1.1 200 OK
< Content-Type: application/json
{
“access_token”:”jWH1al4ncKzu41u40dWckZFAAUxU”,
“access_token_expires_in”:”86399″,
“refresh_token”:”AaVBPYuxs6MxGTFasV7QdZ20Yq7unwVo”,
“refresh_token_expires_in”:”172799″,
“token_type”:”BearerToken”
}
The response will contain an access_token and a refresh_token. The access_token will be only valid for a short time, which means that the application has to refresh the access_token after expiration of the access_token and before the expiration time of the refresh_token, otherwise the user has to go through the authorization step again. The expire times of the access_token and the refresh_token are part of the response.
Rest of the steps is for generating Whitelist Identifier making use of the generated access_token.
- Do a PUT on https://api.meethue.com/bridge/0/config with Body:
{ “linkbutton”: true }
Headers:
Authorization: Bearer <access_token>
Content-Type: application/json
where <access_token> is the access token generated in the previous step.
After this, make sure to press the link button of the Hue Bridge.
- Do a POST on https://api.meethue.com/bridge/ with
Body:
{ “devicetype” : ”<your-application-name>” }
where <your-application-name> is same as the device id used in Step #3.
Headers:
Authorization: Bearer <access_token>
Content-Type: application/json
The above request generates a response, see below for how the response looks:
[
{
“success”:
{
“username” : “n5- MxnX7MtOC68RlkUFFhwLOdblu0lEuUL3w973i”
}
}
]
The above generated username serves as Whitelist Identifier for identification of the device.
For more info on the above steps to be followed, please refer https://developers.meethue.com/develop/hue-api/remote-api-quick-start-guide/
Last part of the approach is all about designing a Mule flow to invoke the required Remote APIs & deploying the application in the Cloud using Anypoint Platform Runtime Manager.
This is how your Mule flow looks:
Steps involved:
- Configure HTTP Listener component as below:
- Select Protocol as HTTP.
- Select Host as ‘All Interfaces [0.0.0.0] (default)’.
- Give Port as ‘8081’.
- Give Base path as ‘/’.
- Give Path as ‘/huesmartlight’.
- Configure HTTP Request component to invoke any one of the Remote APIs as below:
- Select Protocol as HTTPS.
- Give Host as ‘api.meethue.com’.
- Give Base path as ‘/bridge’.
- Select Request Method as ‘PUT’.
- Give Request Path as ‘/{username}/lights/{id}/state’.
- Configure Header to have Basic Authentication as below:
Authorization: ‘Bearer <access_token>’
where <access_token> is the Bearer token generated in the first part.
- Configure URI parameters as below:
username : ‘<whitelist_identifier>’
id : ‘1’
where <whitelist_identifier> is the username generated in the last step of the above first part.
- Deploy your Mule application in the Cloud using Runtime Manager.
Test the API in Postman by doing a POST on http://localhost:8081/huesmartlight.