/** * @mainpage Telldus Core API * * \section 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 \ref sec_other_languages how to use the library in one * of the supported languages by Telldus. * * \section 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. * * \li 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. * \li 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. * * \section sec_basic_usage 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. * * \subsection sec_bu_listing Listing devices * * To list all of the configured devices, look at the following example: * \code * int intNumberOfDevices = tdGetNumberOfDevices(); * for (int i = 0; i < intNumberOfDevices; i++) { * int id = tdGetDeviceId( i ); * char *name = tdGetName( id ); * printf("%d\t%s\n", id, name); * tdReleaseString(name); * } * \endcode * * 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 \c 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 release the * resource after we are done with it by calling tdReleaseString() on any * \c char pointer returned by telldus-core. * * \subsection sec_bu_sending Sending commands to TellStick * * \subsubsection sec_bu_sending_features 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: * \code * 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 ); * } * } * \endcode * * By supplying the methods your application supports, the library can return * customized methods for your application, even if your application doesn't * support the same methods as the device accepts. One example is if your * application only supports ON and OFF, you can control a device that needs UP * and DOWN anyway by using just ON and OFF. * 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: * \code * int methods = tdMethods( id, TELLSTICK_TURNON | TELLSTICK_TURNOFF ); * \endcode * 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 \ref sec_bu_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: * \code * //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 ); * \endcode * * 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. * * \subsubsection sec_bu_controlling_functions 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. * * \paragraph tdTurnOn tdTurnOn() * Devices supporting \c TELLSTICK_TURNON. Most of the normal switches (for lamp * etc.) support this. * \paragraph tdTurnOff tdTurnOff() * Devices supporting \c TELLSTICK_TURNOFF. Almost all of the devices supporting * \c TELLSTICK_TURNON also support this. * \paragraph tdDim tdDim() * Devices supporting \c 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. * \paragraph tdBell tdBell() * Devices supporting \c TELLSTICK_BELL. This is mostly wireless doorbells. * * \subsubsection sec_bu_error_codes Error codes * * If any of the calls in \ref sec_bu_controlling_functions fails it returns * a non-zero error code. This values is one of the \c TELLSTICK_ERROR_* defines. * To translate the error code to a human readable string call the function * tdGetErrorString(). Example: * \code * 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); * } * \endcode * * \subsection sec_bu_device_state Device states * * Since controllable devices only have a receiver and not a transmitter the communication 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. Either sent from the TellStick itself, or sent from another controller (e.g. a remote control) * captured by the Tellstick Duo. In this way it "emulates" a two-way communication. * * To query the device state, use the function tdLastSentCommand() * * Example: * \code * 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); * \endcode * * \subsection sec_bu_sensors Sensors * * Retrieving sensor values can be done in two ways. Either by a polling * interface or by callbacks. The client application can implement one or both * of these interfaces. For callbacks, read more under \ref sec_events. * * Each of the sensors can have one or several value types. Currently only * temperature and humidity are implemented. * * There is no API to add, remove or edit sensors. Each sensor that * TellStick Duo has got any data from is added to an internal list. It is up to * the client application to filter and only show the sensors your are * interested in. * * To iterate over the list of sensors, call tdSensor() repeatedly as long as it * returns \c TELLSTICK_SUCCESS. The parameters \c protocol, \c model, * \c sensorId, and \c dataTypes are sent by reference and will be filled with * the values. * * Example: * \code * char protocol[DATA_LENGTH], model[DATA_LENGTH]; * int sensorId = 0, dataTypes = 0; * while(tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes) == TELLSTICK_SUCCESS) { * //Print the sensor * printf("%s,\t%s,\t%i\n", protocol, model, sensorId); * } * \endcode * * The type of sensor values the sensor supports are stored as flags in the * parameter \c sensorId. Call tdSensorValue() for each type. * * Example: * \code * char value[DATA_LENGTH]; * char timeBuf[80]; * time_t timestamp = 0; * if (dataTypes & TELLSTICK_TEMPERATURE) { * tdSensorValue(protocol, model, sensorId, TELLSTICK_TEMPERATURE, value, DATA_LENGTH, (int *)×tamp); * strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); * printf("Temperature:\t%sÂș\t(%s)\n", value, timeBuf); * } * \endcode * * \section sec_events Events * * To get events from either a TellStick Duo, another software changes the * status of a device, or new sensors values you have to register for a callback. * * \subsection sec_events_registering Registering for callbacks * * For each callback there is a corresponding register function: * \li tdRegisterDeviceEvent() * \li tdRegisterDeviceChangeEvent() * \li tdRegisterRawDeviceEvent() * \li tdRegisterSensorEvent() * * 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. * * Many devices (for example motion detectors) resends their messages many times * to ensure that they are received correctly. If a deviceeventcallback or * rawdeviceeventcallback in turn is calling a controlling function, for example * tdTurnOn, it may be neccessary to implement some solution to wait for the * device to finish its resending, before executing the controlling function. * See how this can be done in the python example. * * \subsection sec_events_callbacks Callbacks * * telldus-core currently implements four different callback function for * different purposes. * * \subsubsection sec_events_callbacks_deviceevent 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. * - int callbackId - id of callback * - void *context - see \ref sec_events_registering for description * * \subsubsection sec_events_callbacks_devicechangeevent 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. * - int callbackId - id of callback * - void *context - see \ref sec_events_registering for description * * \subsubsection sec_events_callbacks_rawdeviceevent RawDeviceEvent * * Use this callback with caution. It outputs everything from a TellStick Duo * without any preprocessing. This can be used to get events from devices not * already configured. * * Parameters: * - const char *data - raw device data * - int controllerId - id of receiving controller, can identify the TellStick if several exists in the system * - int callbackId - id of callback * - void *context - see \ref sec_events_registering for description * * \subsubsection sec_events_callbacks_sensorevent SensorEvent * * This event is fired when a new sensor value is retrieved. * * Parameters: * - const char *protocol - The sensors protocol * - const char *model - The model of the sensor * - int id - The unique id for the sensor. * - int dataType - Flags for which types of data the sensor supports * - const char *value - A human readable string of the data * - int timestamp - The timestamp when the latest value was received * - int callbackId - id of callback * - void *context - See \ref sec_events_registering for description * * \subsection sec_events_example Example * * \section sec_other_languages Notes using other languages than C/C++ * * \subsection sec_ol_pyhon Python * * To use telldus-core in Python, * please have look at the ctypes library. It contains cdll and * windll to load any dynamic link libraries. * * There is also a third party library available: * https://github.com/erijo/tellcore-py * */