SmartApp endpoints are a powerful way to securely control your SmartThings with familiar REST calls GET,POST,PUT or DELETE. You have the freedom to define your URL schema and can pass query values through the URL path or through JSON.
This tutorial will guide you through the process of setting up this App Endpoint Example. After you authorize the app to see specific devices, it will generate a web page of buttons with URLs to toggle your chosen lights and locks.
You can download the full code for the SmartApp Endpoint Example and PHP code to interact with the endpoint. Additional OAuth documentation can be found here.
Step 1: Enable OAuth in the SmartApp
To begin, add a New SmartApp in the IDE. Make sure to click the button to âEnable Oauth in Smart App.â Note the âOAuth Client IDâ and the âOAuth Client Secret.â We will use these later to generate our interface page. After entering the other required fields, click âCreateâ and continue on to coding the app.
Step 2: Configuring the Endpoint Mapping
When coding, youâll add âmappingsâ to your app following the preferences section.
Withing the mappings, we define the URL paths that map to our desired commands.
REST verbs further specify the SmartApp functions that specific URLs will trigger.
For example, in the mapping below, when the path â/switchesâ is hit with a GET request, the function listSwitches is called.
In a similar fashion, if we pass an id number and a command in the path â/switches/09f46871-dc7c-45d0-8f51-2c6d352bf8cz/onâ we will trigger âupdateSwitchâ to execute the âonâ command for the switch with id â09f46871-dc7c-45d0-8f51-2c6d352bf8czâ.
mappings {
path("/switches") {
action: [
GET: "listSwitches"
]
}
path("/switches/:id/:command") {
action: [
GET: "updateSwitch"
]
}
...
}
Step 3: Passing Variables
We access the variables in the path via âparams.â As shown below, we retrieve the id and command as params.command and params.id.
We then call the passed command on the specified id. As easily as that - with a little bit of error checking.
void updateSwitch() {
update(switches)
}
private void update(devices) {
log.debug "update, request: params: ${params}, devices: $devices.id"
def command = params.command
def device = devices.find { it.id == params.id }
//let's create a toggle option here
if (command){
if (!device) {
httpError(404, "Device not found")
} else {
if(command == "toggle")
{
if(device.currentValue('switch') == "on")
device.off();
else
device.on();
}
else
{
device."$command"()
}
}
}
}
As an alternative to passing the variables in the URL path, we could have sent a json string and used it in this manner.
def command = request.JSON?.command
Step 4: Going through the Oauth Process to Interact with the Endpoint
Now, letâs assume youâve installed the full demo code and hit publish in the IDE.
To interact with the endpoint, first find the Client ID and Client Secret you enabled in Step 1 (you can always go back to the âApp Settingsâ page retrieve that info).
Weâre going to create a new PHP program as an example of how to interact with the app endpoint programatically. Note that the PHP code is only used to facilitate the example - no server-size code is actually needed to call our SmartApp endpoint commands.
In the PHP code:
a) The first step is to redirect to Authorize the App with the Client ID and Redirect URL specified.
header( "Location: https://graph.api.smartthings.com/oauth/authorize?response_type=code&client_id=$client&redirect_uri=".$url."&scope=app" ) ;
b) After authorization, the page will be redirected including a code in the query string. We use this code to claim our official access token. In this case, Iâm using a CURL call to request the token as shown below.
$code = $_REQUEST['code'];
$page = "https://graph.api.smartthings.com/oauth/token?grant_type=authorization_code&client_id=".$client."&client_secret=".$secret."&redirect_uri=".$url."&code=".$code."&scope=app";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $page );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST, 0 );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$response = json_decode(curl_exec($ch),true);
curl_close($ch);
$accessToken = $response['access_token']
//In the full example, I redirect back to the PHP page at this point with the access token in the query string so that the URL can be more easily stored for later visits.
c) We then use our access token to collect the full URLs of our endpoints.
$url = âhttps://graph.api.smartthings.com/api/smartapps/endpoints/$client?access_token=â.$_REQUEST[âaccess_tokenâ];
$json = implode(ââ, file($url));
$theEndpoints = json_decode($json,true);
d) Finally, we generate a page building out some possible URLs to send commands to our devices.
foreach($theEndpoints as $k => $v)
{
$switchUrl = "https://graph.api.smartthings.com".$v['url']."/switches";
$access_key = $_REQUEST['access_token'];
$ch = curl_init($switchUrl);
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_key ) );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST, 0 );
$resp = curl_exec($ch);
curl_close($ch);
$respData = json_decode($resp,true);
if(count($respData) > 0) print "<h2>Switches</h2>";
//let's show each of the switches
foreach($respData as $i => $switch)
{
$label = $switch['label'] != "" ? $switch['label'] : "Unlabeled Switch";
print " <h3>$label</h3>";
$onUrl = "https://graph.api.smartthings.com".$v['url']."/switches/".$switch['id']."/on?access_token=".$_REQUEST['access_token'];
print "<a target='cmd' href='$onUrl'>On</a>";
$offUrl = "https://graph.api.smartthings.com".$v['url']."/switches/".$switch['id']."/off?access_token=".$_REQUEST['access_token'];
print "<a target='cmd' href='$offUrl' value='Off'>Off</a>";
$toggleUrl = "https://graph.api.smartthings.com".$v['url']."/switches/".$switch['id']."/toggle?access_token=".$_REQUEST['access_token'];
print "<a target='cmd' href='$toggleUrl'>Toggle</a><BR>";
}
}
Step 5: Putting it all Together
You can run the full code from here in your browser - smartApps with endpoints are installed into your account once you authorize them to access specific devices. See links to download the full source code for the example at the top of the article.
Also, check out this more advanced project that allows the Leap Motion to control light switches through this app endpoint video here: