Telldus/Tellstick Local API with PHP

Robert AndresenInternet of things, Programming, Tutorials 3 Comments

21.01.2016 Telldus announced a closed beta for their Local API on the ZNet Lite. 24.05.2016 they opened the Local API to public beta.

Local API let’s you connect and fetch data directly from the Tellstick ZNet without going through Telldus Live, which can be a huge advantage as it’s faster and more stable.

As long as the Local API is in beta, you will need to contact Telldus support to activate the beta on your Tellstick.

I have been playing around with the Local API the last days, and I finally got it to work. I created a simple PHP-class for the necessary requests. Please keep in mind that this is a quick work-in-progress draft, and it could probably be optimized a bit, throw some errors, etc…

 

TelldusLocalAPI.class.php

<?php
/**
* Class for connecting to Telldus ZNet locally
* Please see official documentation here: http://api.telldus.net/localapi/api/authentication.html
*
* LICENSE: Free to use with no warranty or support
*
* @author Robert Andresen <ra@fosen-utvikling.no
*/

class TellstickLocalApi
{
	
	function __construct()
	{
		$this->AppName = 'Example app';
		$this->BaseURL = "http://0.0.0.0/api/";
	}




	/**
	* Step 1 - Request a request token
	* 
	* Request a request token by performing a PUT call to the endpoint /api/token. 
	* You need to supply the application name as a parameter “app”
	*
	* @return  	stdClass	$result		stdClass Object ( [authUrl], [token] )
	*/
	function get_request_token()
	{
		$curl = curl_init($this->BaseURL.'token');
		$data = array(
			'app' => $this->AppName,
		);
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
		curl_setopt($curl, CURLOPT_HEADER, false);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));

		// Make the REST call, returning the result
		$response = curl_exec($curl);
		curl_close($curl);


		$result = json_decode($response);

		

		return $result;
	}




	/**
	* Step 3 - Exchange the request token for an access token
	* 
	* When the user has authenticated the request token in step 2 the application needs to exchange this for an access token. 
	* The access token can be used in the API requests. 
	* To exchange the request token for an access token perform a GET call to the same endpoint in step 1. 
	* Supply the request token as the parameter “token”.
	*
	* @param  	String		$token		Request token from step 1
	* @return  	stdClass	$result		stdClass Object ( [allowRenew], [expires], [token] )
	*/
	function get_access_token($token)
	{
		// Get cURL resource
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $this->BaseURL.'token?token='.$token);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_VERBOSE, 1);

		$response = curl_exec($curl);
		curl_close($curl);

		$result = json_decode($response);

		// Write access-token to textfile
		$this->write_access_token($result->token);

		return $result;
	}




	/**
	* Refreshing a token
	* 
	* If the user allowed the application to renew the token in steg 2 it can be renewed by the calling application. 
	* The token must be refreshed before it expires. 
	* If the token has expired the authentication must be restarted from step 1 again.
	*
	* @uses $this->get_stored_access_token()
	*
	* @return  	stdClass	$result		stdClass Object ( [expires], [token] )
	*/

	function renew_token()
	{
		// Get access token from textfile
		$authorization = "Authorization: Bearer " . $this->get_stored_access_token();

		// Get cURL resource
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $this->BaseURL.'refreshToken');
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_VERBOSE, 1);
		curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization ));

		$response = curl_exec($curl);
		curl_close($curl);

		$result = json_decode($response);

		
		// Write access-token to textfile
		$this->write_access_token($result->token);

		return $result;
	}




	/**
	* Fetch device/sensor data (Remote procedure call)
	* 
	* To make a requst to a TellStick ZNet API endpoint the token in step 3 must be supplied as a bearer token in the header. 
	* This is an example requesting a list of devices.
	*
	* Call commands:
	*	device:
	*		device/bell
	*		device/command
	*		device/dim
	*		device/down
	*		device/info
	*		device/learn
	*		device/setName
	*		device/stop
	*		device/turnOff
	*		device/turnOn
	*		device/up
	*
	*	devices:
	*		devices/list
	*
	*	sensor:
	*		sensor/info
	*		sensor/setName
	*
	*	sensors:
	*		sensors/list
	*
	*
	* @uses $this->get_stored_access_token()
	*
	* @return  	stdClass	$result		stdClass Object
	*/


	function rpc($call)
	{

		// Get access token from textfile
		$authorization = "Authorization: Bearer " . $this->get_stored_access_token();


		// Get cURL resource
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $this->BaseURL.$call);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_VERBOSE, 1);
		curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization ));

		$response = curl_exec($curl);
		curl_close($curl);

		$result = json_decode($response);

		return $result;
	}




	/**
	* Store the access-token in a textfile
	* 
	* The generated access token after approving the application is required to future calls.
	* This stores it in a textfile. 
	*
	* @return  	Boolean		$result		True/False
	*/

	function write_access_token($token)
	{
		$myfile = fopen("token.txt", "w") or die("Unable to open file!");
		$result = fwrite($myfile, $token);
		fclose($myfile);

		return $result;
	}




	/**
	* Retrieve access-token from textfile
	*
	* @return  	String		$token		Access token
	*/

	function get_stored_access_token()
	{
		$myfile = fopen("token.txt", "r") or die("Unable to open file!");
		$token = fgets($myfile);
		fclose($myfile);

		return trim($token);
	}

}
?>

 

auth.php

First you need to fetch a request token. This token need to be used to authenticate your app, by clicking the link. The link will open a new window, where you can select some access options. After the app is authenticated, you can exchange the request token for an access token by going back to the page and clicking the other link.

After exchanging the request token for an access token, this will create a textfile in your root directory with the access token. Make sure you have write permissions to create and write to the textfile. You can also create a file named «token.txt» manually.

<?php
	require_once('TelldusLocalAPI.class.php');

	$obj = new TellstickLocalApi;
	$requestToken = $obj->get_request_token();
?>

<a href="<?php echo $requestToken->authUrl; ?>" target="_blank">Authenticate the app</a><br />
<a href="access_token.php?token=<?php echo $requestToken->token; ?>" target="_blank">Exchange the request token for an access token</a>

 

request.php

After the authentication is done, you can start fetching data directly from your Tellstick ZNet.

<?php
	require_once('TelldusLocalAPI.class.php');

	$obj = new TellstickLocalApi;


	// Get devices
	$result = $obj->rpc('devices/list?supportedMethods=3');

	echo '<pre>';
		print_r($result);
	echo '</pre>';


	// Get sensors
	$result = $obj->rpc('sensors/list');

	echo '<pre>';
		print_r($result);
	echo '</pre>';


	// Get sensordata from sensor with ID 1
	$result = $obj->rpc('sensor/info?id=1');

	echo '<pre>';
		print_r($result);
	echo '</pre>';
?>

 

Here is a screenshot of the request.php. I don’t have any devices connected to my new ZNet Lite v2 yet, so that array is empty.

local_api_test