CherryPy is a full webserver including a server side framework. It was chosen because it is reasonable easy to use, still possible to add things like authentication later on. Install cherrypy on the raspberry pi by:
> pip install cherrypy
It is possible to generate a complete webpage from inside python, but it soon tends to create disorder in the code. It is easier to have static html pages on the file system and only generate dynamic content from the code. How is the static html page merged together with the dynamic content? By the use of a template engine. A template engine makes it possible to insert dynamic data into a page at specific places. How is it one? The template engine parses the page, inserts parameters or executes the python code , and generates the final page as html which sent back to the web-browser. The template engine jinja2 was picked, since jinja2 seemed to have the biggest community of the existing ones (2015). Install jinja2 on the raspberry pi by:
> pip install jinja2
A web application in CherryPy is written as a class containing several methods, and in the __main__ method, the application is instantiated together with the web server. If marked correctly, a method in the class is possible to access directly via a REST API call.
Setup is both a utility command and a library implemented in python. It is initialized by the json config file defining the switches and their schemas (described on the previous blog post).
json registers +---------------------+
config +----> setup.py +-----------> | |
+ | Crontab daemon |
| | |
| | calls
| | at XX:YY
| direct v
The program reads each chunk of definitions in the config file translating the schemas into ‘turn on’ and ‘turn off’ commands which are registered in the crontab daemon of linux. In case the actual time is within an interval, the ‘turn on’ command is called directly. Registered on/off commands are run by crontab
at the specified time e.g. sunset. The turn.py
command is used to turn on and off, it is also a simple python program – presented in “Using python to control telldus”
. The setup command might be run from the command line by supplying the json config file or if using it as a library interfacing it with other programs or a webserver.
The setup.py program is divided into three classes SetupSchema, SetupCron and SetupTurn. The class SetupSchema is called from main to parse the configuration json file (described in former post). For each new definition of a switch a callback is executed to interested instances. In this case there are two instances interested, one from the class SetupCron and the other from the class SetupTurn – see image below. The class SetupCron registers ‘turn on’/’turn off’ commands in the crontab daemon, the class SetupTurn on the other side checks if the switch shall be on/off right now and executes turn.py directly.
| subscribes |
| +--> SetupCron.py |
| | |
| SetupSchema.py | |
| | |
| +--> SetupTurn.py |
There are a number of switches in the house, most of them controlling lamps but also other things like the printer for example. Most of the switches are of the brand ‘Nexa’ and selflearning which makes it easy to control using the tellstick.
A new switch has to be configured in two different ways. The first configuration file is the tellstick.conf used by the telldus service daemon. In this configuration file, the id is specified as well as the name and the protocol of the switch. It is quite easy to find the protocol name of the 433 MHz communication by looking into wikis/forums of telldus.
The second configuration file is the one defining the on/off intervals of the switches. First of all having a separate file defining the intervals gives the possibility to differ between intervals at normal occasion and trip/vacation.
The format of the configuration file is json-format since it is very easy to read directly into a python program. In more detail it is a list of all switches where each switch has a structure containing a textual description, the device id in telldus, and the schema/interval defined as either always (on), never (on), sun, night, or :
"text" : "textual description e.g. lamp in working room",
"name" : "device id in telldusd", "schema" : schema either "always", "never", "sun", "night", ":"
The schema/interval sun is defined as turning switch on 40 minutes before sunset and then turning it off at a defined bed time which is one o´clock at night.
Here is an excerpt from the existing normal.json of the house:
"text" : "Prydnadslampa 1",
"name" : "wallswitch3",
"schema" : "sun"
"text" : "Pappas sänglampa",
"name" : "wallswitch4",
"schema" : "always"
"text" : "Linneas sofflampa",
"name" : "wallswitch5",
"schema" : "night"
In vacation.json the second switch above, the schema is changed from ‘always’ to ‘sun’ to give an illusion of somebody in the bedroom (does it fool anybody? – probably not).
The whole point of having a tellstick connected to a raspberry pie is to let the raspberry control the switches in the house in a defined way. A telldus duo is also able do more like monitoring temperature and humidity sensors as well as PIR/magnetic sensors.
Ok, let’s stick to controlling the switches. One way is to build a program that falls asleep and then wakes up at certain times. In Linux however this functionality is built into the system process crontab. It is possible to configure crontab to run any command at a certain time each day for example. Crontab is very flexible and it is possible to have other configuration but the example covers what is most useful for lamp switches. How do you configure crontab? As always there is a easy to use library called ‘python-crontab’ where it is possible to configure crontab in an intuitive way.
Most often a lamp switch shall be turned on when dusk appears. However sunset is at different hours depending on the date and where you live geographically since the earth is moving around it’s axle. Luckily it is possible to calculate the dusk if the date and the geographically position is given. Another python library called ‘astral’ has everything needed since it possible to give it a location (through google map service) as well as the actual date, receiving the time of sun dawn/sun dusk/sun set.
Installing the mentioned libraries and their dependencies:
> pip install python-crontab
> pip install astral
> pip install pytz
> pip install nptime
Next post is how to write the setup program configuring the crontab using the libraries mentioned in this post!
Coming from a Linux environment, the Windows eco-system seems a bit frugal, at least from a developer point of view. However once you find NuGet and that it is included in Visual Studio, things seem a little bit more promising. However it does not end there….
Chocolatey is a package manager for Windows built on NuGet. It has a central repository and if choosing to install a package all it’s dependencies are also downloaded like rpm and apt on Linux. Nice!
Decided to give it a try and headed over to the Chocolatey site. The install command looks frightening but it is quite easy – just start powershell as administrator and copy & paste the install command from start page. Now Chocolatey is installed!
The site contains a large package directory divided into ‘approved’ packages and ‘waiting for moderation’. Packages having the status ‘waiting for moderation’ is used on your own risk since they have not been revised.
The first three packages installed using the Chocolately utility: choco
Cmder – finally a descent shell on windows with all linux commands like ssh etc.
> choco install cmder
Python – the python programming environment
> choco install python
Pip – tool making installing python libs easy
> choco install pip
Filezilla – makes ftp and sftp easy on windows
> choco install pip
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
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:
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)
if __name__ == "__main__":
if len(sys.argv) == 3:
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
In part 1 we assured that the service was following best practice in linux be creating a separate ‘telldus’ user and letting the device handle also be owned by that ‘telldus’ user.
Now it is time to configure the light switches for the Telldus service. The light switches are defined in several JSON data structures, one for each light switch. The format is defined by Telldus on the following page.
For example here is the definition from /etc/tellstick.config of two switches from Conrad:
id = 1
name = "wallswitch1"
protocol = "risingsun"
model = "selflearning:conrad"
house = "31942"
unit = "1"
id = 2
name = "wallswitch2"
protocol = "risingsun"
model = "selflearning:conrad"
house = "32170"
unit = "15"
The id is a simple identifier increased for each switch. The name is a symbolic name of the switch which is posssible to use in bash commands or when using one of the API to the telldus service. Protocol/model is often easy to find out either by looking at page
or googling. The parameters are dependant on the protocol/model but in the case of the risingsun protocol these identifiers are learnt by the switch during the selflearning sequence.
Once the telldus.config file is finished – start or restart the telldus service:
[ ok ] Restarting the Telldus TellStick daemon: telldusd.
The command ‘tdtool’ is a command utility communicating with the telldus service. Here are some examples.
List the switches defined above:
> tdtool --list
Number of devices: 2
1 wallswitch1 OFF
2 wallswitch2 OFF
Learn a selflearning-switch the parameters:
> tdtool --learn wallswitchxx
Turning on a switch:
> tdtool --on wallswitch1
Turning off a switch:
> tdtool --off wallswitch1