Tag: Telldus

Supervising a Telldus Daemon

It is rare but sometimes it happens – the telldus daemon responsible for communicating with the Telldus Duo hardware has disappeared from the processlist, crashed or exited silently. This is not acceptable on an embedded system where processes shall have 100% uptime. The preferred way is to have some sort of supervisor which is responsible for restarting the process if it disappears.

Who is the naturally supervisor? Well, the process that started the process to be supervised. In Linux the first process started is either the old init or the newer systemd, which then starts all the other processes according to runlevels and dependencies (systemd) or sequence number (init/rc). There are a number of possible solutions for supervising using either init or systemd. A quick check on ‘google’ gives a couple of solutions, others probably exists as well:

  • daemontools – a supervisor which monitors processes, possible to use with init.
  • monit – a supervisor which monitors processes but also have a wealth of other monitoring possibility. Seems more targeted to server systems than embedded.
  • built in supervising in systemd – the systemd has a simple supervisor built in which restarts processes.
The websolution and the telldus daemon nowadays run on the raspbian called ‘Jessie’. Raspbian ‘Jessie’ has systemd as the first process that starts all other processes. The existing solution is built on init.d bash-scripts with links to the different runlevels (rcX). I decided to go with the systemd as the supervisor since it was time to transfer the init.d scripts to systemd services and only simple supervising was needed anyways.

In systemd you don’t write a script, instead you define a service having different properties and dependencies. This service configuration is put into /etc/systemd/system/<name>.service. The syntax is the same as .INI files on windows. See Service Configuration for details.

Telldus daemon as a systemd service

Explanations:

Type=forking

The telldus daemon is a forking daemon, i.e. it is forked off the starting process to be able to be automatically attached to the process having pid 1 (systemd in this case) making it independant of the terminal (tty).

 PIDfile=/var/run/telldusd.pid

The PID number is saved into this file when fork has been made, making it possible to find out the id of the process.

Restart=always

Always restart regardless the case abort, exception, signal or exit via return code.

Websolution (cherrypy) as a systemd service

Explanations:

After=network.target

Dependant on network connection before starting up.

Type=simple

Ordinary process i.e. doesn’t return if started since it is listening on network connections

User=root

Start process as root, since the webserver will switch to telldus user as soon as possible.
Environment=”PYTHONPATH=/usr/local/bin/setup”
Sets and exports the env. variable PYTHONPATH to the started process.

To make the services start call:

sudo systemctl enable telldusd
sudo systemctl enable cherrytelldus

Both solutions were tried out by killing the processes abruptly using ‘kill -kill ‘ and verified that they were restarted.

A Tellstick Sensor that Twitters

There are tellstick sensors measuring temperature and humidity, not with high precision but still ok if monitoring the house when being away. The sensors might be connected to a Tellstick NET from Telldus which sends all the measurement values up to the cloud (Telldus Live). However it is always a hassle to remember how to login to Telldus Live just to check the temperatures of the sensors.

It would be nice if one could read the temperature from some app already in use – twitter fits very well since it allows short text messages and it is possible to read both from an app and from a PC (no login required).

Telldus has an API to Telldus Live having the address: api.telldus.com. The API is a REST interface possible to access using GET requests and the text answers are in simple JSON format. It is definitely possible to to periodically fetch the temperature value of a sensor. Next step is to push the temperature value up to a twitter account. The twitter REST API was released as early as 2006 and have to be considered mature – see api.twitter.com. By using this API it is possible to automatically twitter status message and it might for example be used by IoT devices.

The Telldus API and the Twitter API use the standard OAuth (Open Authorization) to authorize clients. This standard is used by many companies including Facebook and Google. The standard makes it possible for service vendors to give limited access to certain parts of their API to registered clients. The registered clients might be applications, mobile apps, or back-end systems. OAuth requires you to generate 2 pair of keys, where one pair is authorization of the user or application (consumer key/consumer secret) and the other pair is authorization of the service request (access token/access secret). Once calling one of the REST API:s the public key is put directly in the HTTP authorization header and the secret key is used together with the other parameters to create a hash signature also going into the header.

If searching on pypi (the python package index), there is already a python library ‘tellive‘ for connecting to Telldus Live. The tellive library contains a client class which takes care of the constructing of the  REST url and the HTTP authorization header. However you still have to know a bit of how the REST api:s work to be able to use the correct arguments. Twitter on the other hand has several independent implementations calling the REST api:s. Among them is the python-twitter which seems pythonic and stable.

Now we have everything to put together a script which uses both the libraries ‘tellive-py’ and ‘python-twitter’:

The class ‘OAuthCredentials’ contains the two key pairs (consumer and access). The function ‘get_temperature’ uses the ‘tellive’ library by listing all sensors and find the value of requested sensor. The function ‘send_to_twitter’ uses the ‘python-twitter’ library to post a string containing the temperature to the twitter account belonging to the specified customer keys. Finally decide how often the script will run and make a crontab configuration.

Turn.py – Using Python to Control the Telldus

There are at least two python libraries for  communicating with the Telldus service. One of them is ‘tellcore-py’ which is an active github project (link). Installing the package by using pip (“python install python”):

 > pip install tellcore-py

The tellcore library is wrapper of the telldus C/C++ library which communicates directly with the Telldus service (the telldusd – daemon). This service was configured in last blog post and it uses the libusb library to send messages/commands via usb to the Tellstick DUO – see picture below.

                              +               
                 +---------+  |               
 tellcore.py +-> |telldusd/|  |  Tellstick DUO
                 |libusb   +---->             
                 +---------+  |               
                              +               
                                  

However in this case only interesting in a narrow use of the library i.e. turning on and off the switches. Later on if buying sensors it will be interesting collecting data through the use of this library.

Here is a small utility ‘turn.py’ written in python using the library, doing what I need – not more not less:

#!/usr/sbin/python
import sys
 import tellcore.telldus
 
 core = tellcore.telldus.TelldusCore()
 
 def turn(state, device):
     devices = [d for d in core.devices() if d.name == device or device == 'all']
 
     for d in devices:
        m = getattr(d, "turn_" + state)
        m()
   
 if __name__ == "__main__":
     if len(sys.argv) == 3:
        turn(sys.argv[1], sys.argv[2])
     else:
        print "turn "
 

Trying it out by first setting the executable flag and then running it directly by turning on/off switches

 > chmod u+x turn.py
 > turn on wallswitch3
 > turn off all

Configure the Telldus Service – Part 1

First stop the service and then create a separate user ‘telldus’ with no login or home directory. The group ‘telldus’ which is connected to the ‘telldus’ user is also created.

/etc/init.d/telldusd stop
adduser --no-create-home --disabled-login --gecos "" telldus

Create the config file of the service daemon: ‘/etc/tellstick.conf’ and add the following two rows:

user = "telldus"
group = "telldus"

Now the service daemon will start up and change process owner to ‘telldus’.

Let’s focus on the tellstick device (in my case the tellstick duo). Connect it to the USB host port of the Raspberry Pi. Verify that it is detected and note the vendor id and product id:

> lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 1781:0c31 Multiple Vendors Telldus TellStick Duo

The tellstick is detected which is shown at the last row, and vendor id: 1781/product id: 0c31.

The service daemon needs a device handle in /dev to be able to communicate with the device.

Newer kernels contains the udev subsystem handling plugindevices, making it possible to write a rule like: each time this device is plugged in, then create this type of device handle.

The tellstick device uses the FTDI HW component to make it easy to communicate using serial usb. The FTDI device driver is included with the kernel as a loadable device driver. A loadable device driver is possible to load dynamically by running the command ‘modprobe’.

Next step is to write a udev rule which matches the device (vendor id/product id) and runs the modprobe command as well as writing to /sys/bus/usb-serial/drivers/ftdi_sio/new_id to make the device handle appear.

Start by creating the file ’99-ftdi.rules’ in ‘/etc/udev/rules.d’:

ACTION==”add”, ATTRS{idVendor}==”1781″, ATTRS{idProduct}==”0c31″, RUN+=”/sbin/modprobe ftdi_sio” OWNER=”telldus” GROUP=”telldus” RUN+=”/bin/sh -c ‘echo 1781 0c31 > /sys/bus/usb-serial/drivers/ftdi_sio/new_id'”

This rule loads the FTDI driver and creates the device handle ‘/dev/ttyusb0’ owned by telldus.
Restart udev subsystem (making it reread all the the rules):

> udevadm control --reload

Verify that ‘/dev/ttyUSB0’ appears when inserting the tellstick device.

Finally we update the config file ‘/etc/tellstick.conf’ with the following line pointing out the device handle:

deviceNode = "/dev/ttyUSB0"

Compiling/Installing the Telldus Service on Raspberry Pi

Time to take a big breath!

Basicly two alternatives either compiling on the pi or cross-compiling on my linux-box.

Since the Telldus-server is a rather small server and knowing that setting up a cross-compiling environment often takes more time than expected, so the choise is easy!

Starting off by installing the development environment on the pi by doing the following:

apt-get install g++
apt-get install cmake

The ‘g++’ is the gnu C++ compiler including all other necessary libraries, ‘cmake’ is a cross-platform make.

Found an excellent description on how to compile telldus on raspberry pi – Link
Basicly repeating it:

nano /etc/apt/sources.list.d/telldus.list
Add the following to file above "deb-src http://download.telldus.com/debian/ stable main"
wget http://download.telldus.se/debian/telldus-public.key
apt-key add telldus-public.key
apt-get update
apt-get install build-essential
apt-get build-dep telldus-core
apt-get install cmake libconfuse-dev libftdi-dev help2man
mkdir -p ~/src/telldus-core

cd ~/src/telldus-core
apt-get –compile source telldus-core
dpkg --install *.deb

Yes! The last install statement is returning “[ ok ] Starting the Telldus TellStick daemon : telldusd.” which is a receipt that the server has started. There is a start/stop script in /etc/init.d/telldusd and this script is run during startup. It is also possible to use this script to restart the server when configuration has been changed.