Telldus Core API

Introduction

This is the guide to Telldus TellStick SDK. Even though all examples are written in C/C++ most of the code has a direct eqvivalent function in the other languages. See Notes using other languages than C/C++ how to use the library in one of the supported languages by Telldus.

Idea

All of the devices used by TellStick must be predefined before they can be used in any software. Under all platforms this can be done with the software TelldusCenter but under Linux this can also be done by editing the file /etc/tellstick.conf with your favorite text editor.

Having the devices preconfigured is an advantage to both the developer and the end user.

  • The end user might use more then one program for controlling his/her TellStick. By having the devices preconfigured he/she does not have to reconfigure the same devices twice. If some settings change in one of the devices, this change will affect all softwares using Telldus TellStick SDK.
  • Telldus continuously adds support for new devices. If a software defines it's own devices, the developer will have to keep the software up to date with new devices and settings implemented by Telldus. By querying Telldus Tellstick SDK all the new devices will be available automaticly to the end user.

Basic usage (telldus-core)

Telldus provides a non-gui library to list, query and control the devices called telldus-core. To initiate the library a call to tdInit() must be made. This call will open up all controllers (e.g. a TellStick) and start listening for events from them. When you are done with telldus-core, call tdClose() to allow the library to clean up after itself.

Listing devices

To list all of the configured devices, look at the following example:

 int intNumberOfDevices = tdGetNumberOfDevices();
 for (int i = 0; i < intNumberOfDevices; i++) {
   int id = tdGetDeviceId( index );
   char *name = tdGetName( id );
   printf("%d\t%s\n", id, name);
   tdReleaseString(name);
 }

First, we call tdGetNumberOfDevices(). This returnes the total number of devices configured. We then iterate over all of the devices with the index in the variable i. Since the devices could change between runs of the program we can not be sure that the index points to the same device between two runs of the program. That is why every device has it's own unique id that is safe to store in a configuration file. Two different devices can never share the same device id.

The call to tdGetDeviceId() returns the id for a specific index. This function should only be called in a loop iterating over all of the devices. After we have found the id for a device it is safe to store this or use it in the rest of the program.

The next two lines of code queries the device for it's name with a call to tdGetName() and then displays it to stdout. Finally we must relase the resource after we are done with it by calling tdReleaseString() on any char pointer returned by telldus-core.

Sending commands to TellStick

Device features

TellStick can control many different types of devices that support different features. For example, a bell does not support turning the on-signal and not all lamp switches support dimming. Call tdMethods() to find out what a specific device supports:

 function checkFeatures( int id ) {
   int supportedMethods = TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_BELL;
   int methods = tdMethods( id, supportedMethods );
   if ( methods & TELLSTICK_TURNON ) {
     printf( "The device %d support tdTurnOn()\n", id );
   }
   if ( methods & TELLSTICK_TURNOFF ) {
     printf( "The device %d support tdTurnOff()\n", id );
   }
   if ( methods & TELLSTICK_BELL ) {
     printf( "The device %d support tdBell()\n", id );
   }
 }

By supplying the methods the application supports, the library can be backwards compatible. Let's say that the client application only supports turning on and off. The call to query a device for it's methods should be:

 int methods = tdMethods( id, TELLSTICK_TURNON | TELLSTICK_TURNOFF );

If the device in the above example is a device only supporing TELLSTICK_BELL, the library will instead return TELLSTICK_TURNON, making the client application still able to control the device. When you know which features a device supports it is safe to call the controlling functions described in Controlling functions.

When calling tdMethods() all of the supported methods should be passed in one call. Do not call tdMethods() for each of the supported methods. Look at the following example:

 //Correct
 int methods = tdMethods( id, TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_BELL );
 //Wrong
 int turnOn = tdMethods( id, TELLSTICK_TURNON );
 int turnOff = tdMethods( id, TELLSTICK_TURNOFF );
 int bell = tdMethods( id, TELLSTICK_BELL );

Another thing to note is if you are developing a library intended for thirdparty use. You should not hardcode which methods are supported by the library. It is always up to the application implementing the methods to supply the methods it supports.

Controlling functions

TellStick has a couple of functions for controlling devices. Each of them should only be called if the device support the feature.

These functions all return zero if the call was successful and non-zero otherwise.

tdTurnOn()

Devices supporting TELLSTICK_TURNON. Most of the normal switches (for lamp etc.) support this.

tdTurnOff()

Devices supporting TELLSTICK_TURNOFF. Almost all of the devices supporting TELLSTICK_TURNON also support this.

tdDim()

Devices supporting TELLSTICK_DIM. This is a quite unusual feature for dimmers. Many dimmers on the market that are dimmable have no way for sending a specific level which means it does not support this feature.

tdBell()

Devices supporting TELLSTICK_BELL. This is mostly wireless doorbells.

Error codes

If any of the calls in Controlling functions fails it returns a non-zero error code. This values is one of the TELLSTICK_ERROR_* defines. To translate the error code to a human readable string call the function tdGetErrorString(). Example:

 printf("Error: %s\n", tdGetErrorString( TELLSTICK_METHOD_NOT_SUPPORTED ) );
 //Error: The method you tried to use is not supported by the device
 int retval = tdTurnOn( deviceID );
 if (retval != TELLSTICK_SUCCESS ) {
   char *errorString = tdGetErrorString( retval );
   printf("Error: %s\n", errorString );
   tdReleaseString(errorString);
 }

Device states

Since TellStick only has a transmitter and not a receiver the communation is one-way. This means that telldus-core will never know for sure which state a reciever has. Instead, the library remembers which command was last sent. In this way it "emulates" a two-way communication.

To query the device state, use the function tdLastSentCommand()

Example:

 char *name = tdGetName( id );
 int state = tdLastSentCommand( id );
 if (state == TELLSTICK_TURNON) {
   printf("%s is on\n", name);
 } else if (state == TELLSTICK_TURNOFF) {
   printf("%s is off\n", name);
 } else {
   printf("%s is in an unknown state\n", name);
 }
 tdReleaseString(name);

Events

To get events from either a TellStick Duo or if another software changes the status of a device you have to register for a callback.

Registering for callbacks

For each callback there is a corresponding register function:

  • tdRegisterDeviceEvent()
  • tdRegisterDeviceChangeEvent()
  • tdRegisterRawDeviceEvent()

These all work in the same way. The first parameter is a function-pointer to the callback function. The second parameter is an optional void pointer. This can be anything and is dependent on the implementation. This object will be sent back to each call to the callback function. The functions return an integer which is an id to the specific callback. This is is sent as a parameter in each call and should also be used for unregister the callback.

Please note that the callback will be called by another thread than the thread used by the application and some measures must be taken to synchronize it with the main thread.

Callbacks

telldus-core currently implements three different callback function for different purposes.

DeviceEvent

This event is fired when the state of a device changes. This can either occur via a remote control, but can as well occur via another software on the computer.

Parameters:

  • int deviceId - The device id of the device that changed.
  • int method - The new state. Can be TELLSTICK_TURNON, TELLSTICK_TURNOFF etc.
  • const char *data - For some methods this contains data. For TELLSTICK_DIM this hold the current value.

DeviceChangeEvent

This event is fired when the data around a device is changed. It can only be triggered by another software. Use this callback to keep your list of devices in sync.

Parameters:

  • int deviceId - The device id of the device that changed.
  • int changeEvent - What was changed. This can be:
    • TELLSTICK_DEVICE_ADDED - A new device was added. The parameter deviceId holds the id of the new device.
    • TELLSTICK_DEVICE_REMOVED - A device was removed, the parameter deviceId holds the id of the removed device.
    • TELLSTICK_DEVICE_CHANGED - The settings of a device changed. The next parameter holds what was changed.
  • int changeType - If changeEvent is TELLSTICK_DEVICE_CHANGED this parameter holds what was changed. It can be one of the following:
    • TELLSTICK_CHANGE_NAME - Use tdGetName() to read the new name.
    • TELLSTICK_CHANGE_PROTOCOL - Use tdGetProtocol() to read the new value.
    • TELLSTICK_CHANGE_MODEL - Use tdGetModel() to read the new value.

RawDeviceEvent

Use this callback with caution. It outputs everything from the Duo without any preprocessing. This can be used to get events from devices not already configured.

Example