Here is a quick writeup of the protocol for the iKettle taken from my
Google+ post
earlier this month. This protocol allows you to write your own software
to control your iKettle or get notifications from it, so you can integrate
it into your desktop or existing home automation system.

The iKettle is
advertised as the first wifi kettle, available in UK since February 2014. I
bought mine on pre-order back in October 2013. When you first turn on the
kettle it acts as a wifi hotspot and they supply an app for Android and iPhone
that reconfigures the kettle to then connect to your local wifi hotspot instead.
The app then communicates with the kettle on your local network enabling you
to turn it on, set some temperature options, and get notification when it
has boiled.

Once connected to your local network the device responds to ping requests and
listens on two tcp ports, 23 and 2000. The wifi connectivity is enabled by
a third party serial to wifi interface board and it responds similar to a
HLK-WIFI-M03. Port 23 is used to configure the wifi board itself (to
tell it what network to connect to and so on). Port 2000 is passed through
to the processor in the iKettle to handle the main interface to the kettle.

Port 2000, main kettle interface

The iKettle wifi interface listens on tcp port 2000; all devices that connect
to port 2000 share the same interface and therefore receive the same messages.
The specification for the wifi serial board state that the device can only
handle a few connections to this port at a time. The iKettle app also uses
this port to do the initial discovery of the kettle on your network.

Discovery

Sending the string "HELLOKETTLE\n" to port 2000 will return with "HELLOAPP\n".
You can use this to check you are talking to a kettle (and if the kettle has
moved addresses due to dhcp you could scan the entire local network looking
for devices that respond in this way. You might receive other HELLOAPP
commands at later points as other apps on the network connect to the kettle.

Initial Status

Once connected you need to figure out if the kettle is currently doing
anything as you will have missed any previous status messages. To do
this you send the string "get sys status\n". The kettle will respond with
the string "sys status key=\n" or "sys status key=X\n" where X is a single
character. bitfields in character X tell you what buttons are currently
active:

Bit 6

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

100C

95C

80C

65C

Warm

On

So, for example if you receive "sys status key=!" then buttons
"100C" and "On" are currently active (and the kettle is therefore
turned on and heating up to 100C).

Status messages

As the state of the kettle changes, either by someone pushing the physical button
on the unit, using an app, or sending the command directly
you will get async status messages. Note that although the status
messages start with "0x" they are not really hex. Here are all
the messages you could see:

sys status 0x100

100C selected

sys status 0x95

95C selected

sys status 0x80

80C selected

sys status 0x100

65C selected

sys status 0x11

Warm selected

sys status 0x10

Warm has ended

sys status 0x5

Turned on

sys status 0x0

Turned off

sys status 0x8005

Warm length is 5 minutes

sys status 0x8010

Warm length is 10 minutes

sys status 0x8020

Warm length is 20 minutes

sys status 0x3

Reached temperature

sys status 0x2

Problem (boiled dry?)

sys status 0x1

Kettle was removed (whilst on)

You can receive multiple status messages given one action, for example
if you turn the kettle on you should get a "sys status 0x5" and a
"sys status 0x100" showing the "on" and "100C" buttons are selected.
When the kettle boils and turns off you'd get a "sys status 0x3" to
notify you it boiled, followed by a "sys status 0x0" to indicate all
the buttons are now off.

Sending an action

To send an action to the kettle you send one or more action messages
corresponding to the physical keys on the unit. After sending an
action you'll get status messages to confirm them.

set sys output 0x80

Select 100C button

set sys output 0x2

Select 95C button

set sys output 0x4000

Select 80C button

set sys output 0x200

Select 65C button

set sys output 0x8

Select Warm button

set sys output 0x8005

Warm option is 5 mins

set sys output 0x8010

Warm option is 10 mins

set sys output 0x8020

Warm option is 20 mins

set sys output 0x4

Select On button

set sys output 0x0

Turn off

Port 23, wifi interface

The user manual for this document
is available
online, so no need to repeat the document here. The iKettle uses the device
with the default password of "000000" and disables the web interface.

If you're interested in looking at the web interface you can enable it by
connecting to port 23 using telnet or nc, entering the password, then issuing the commands
"AT+WEBS=1\n" then "AT+PMTF\n" then "AT+Z\n" and then you can open up a webserver on port 80
of the kettle and change or review the settings. I would not recommend you
mess around with this interface, you could easily break the iKettle in a way
that you can't easily fix. The interface gives you the option of uploading
new firmware, but if you do this you could get into a state where the kettle
processor can't correctly configure the interface and you're left with
a broken kettle. Also the firmware is just for the wifi serial interface,
not for the kettle control (the port 2000 stuff above), so there probably
isn't much point.

Missing functions

The kettle processor knows the temperature but it doesn't expose that in any
status message. I did try brute forcing the port 2000 interface using
combinations of words in the dictionary, but I found no hidden features (and
the folks behind the kettle confirmed there is no temperature read out). This
is a shame since you could combine the temperature reading with time and figure
out how full the kettle is whilst it is heating up. Hopefully they'll address
this in a future revision.

Security Implications

The iKettle is designed to be contacted only through the local network - you
don't want to be port forwarding to it through your firewall for example because
the wifi serial interface is easily crashed by too many connections or bad
packets. If you have access to a local network on which there is an iKettle you
can certainly cause mischief by boiling the kettle, resetting it to factory
settings, and probably even bricking it forever. However the cleverly designed
segmentation between the kettle control and wifi interface means it's pretty
unlikely you can do something more serious like overiding safety (i.e. keeping
the kettle element on until something physically breaks).

When I moved to a new house in 2001 I designed and installed my own home-brew
home automation system in it to control things like the heating, lighting,
alarm system, and more. The messaging system I picked was to use standard
XMPP (Jabber) because most platforms have existing open source XMPP libraries
so writing clients is easy. The back-end is just a load of XMPP bots written
in Perl. Around the house I had a number of Fujitsu Point 1600 tablets
running an interface I designed and wrote using Perl/Tk. The tablets are
great, but they're starting to show their age with limited resolution
of 800x600 and CPU speed making full-screen video not really possible.

So last year I obtained an Archos 101 10.1" android tablet with the plan being
to replace the existing tablets with android powered ones. It was a good excuse
to dust off the old skills and learn programming apps for Android. Converting
the app was straightforward and tooks a couple of weekends, troubles with the
tablet took quite a bit more work.

Finding a way to mount the Archos tablet on a wall proved tricky, the back
of the device isn't perfectly flat and it has an annoying desk stand in
the middle. I ended up using a PadTab
for mounting, but having to custom modify it to handle not being in the
centre of the device, and add thick sticky strips (normally used to dampen
fans). The build quality of these tablets is pretty poor.

The display panel on the tablet isn't very good either and has limited viewing angles
from three sides, so in order to be able to see the screen when mounted to
the wall I had to turn it upside down. Android can happily handle a rotated
display, the only downside is that the Archos logo is the wrong way up (a bit of
black tape covers it up now).

I left the Archos mounted on the wall and running for a week, permanently
attached to its charger. At the end of the week I noticed it wasn't sitting
straight on the wall, and in fact the internal batteries had both swelled up
and burst out of the case. I read online a few other stories from folks who
had bought Archos tablets which had failed in the same way, I guess they're
really not designed to be left on charge permanently (that's really bad
design Archos, this could have easily caught fire!)

I figured I didn't really need to have batteries installed, the tablet is
going to be permanently powered on anyway, and it would be safer to leave
the house knowing there was no risk of exploding batteries. So I took the
tablet apart and removed them. Without batteries the Archos starts its
power up cycle, displays a logo, then gets to a certain part of the boot process
and powers down. I guess it does a check on the state of the batteries
and it fails. This presented a real problem and I gave up trying to
use the tablet. Over the Christmas holidays I heard that you could flash an
alternative OS, CyanogenMod, and that actually booted and ran just fine without batteries,
but it wasn't stable and featured enough for running the Home Automation app I'd written.

So I decided to try to debug the Archos OS, so connected it to USB to get
debug messages, and interestingly it powered up perfectly first time. Removing
the USB connection caused it to lock up a few seconds later. Strange
behaviour! I tried just connecting power to the USB port, and that worked
too. So if you want to run your Archos 101 android tablet without internal
batteries you can, but you need to splice your power cable and feed 5v to
both the power socket and the USB socket.

So now I had a working tablet again I changed the power adaptor so it
mounted neatly against the wall:

We keep all our friends and family contacts in a single text file in vCard
format. We sync this file to our phones (mobile and house DECT phones) and home
automation system (for caller ID and phone book). I also print out a copy to
take when travelling. Except I rarely print out an update as I've failed to
find any useful program to pretty print the contacts. Previously I used a quick
hack script in perl to convert the vcard entries to HTML, but it wasn't clever
enough to handle page breaks and needed manual setting all the margins and page
sizes correctly. I like to print it to fit in my paper planner, a Compact size
Franklin Covey planner system.

I've been using Scribus for a few months,
mostly for our
wedding invites and
stationary, and spotted that Scribus had a Python API. So a few hours later and
out has popped a Python script you can use to pretty print a vCard vcf file,
handling page breaks, images, and large margins to skip the hole punches.

You'll also need the python vobject library installed
if you haven't already got it

Use the "Script"
"Execute Script" option, find and select vcf2scribus.py and
hopefully you'll end up with something like this:

You can then save it as a pdf or print it direct.

The script is a bit of a hack and has hard-coded page sizes, fonts, margins,
vcard sections used, and so on. But I figure it might save someone a couple of
hours and only needs a bit of modification to suit. It would be fairly easy to
extend the script to use the Scribus API to let folks select the vcard file,
page sizes, fonts, and things. Bonus points if you fix it to figure out the final sizes of the
images and right align them. This is my second ever python program so no
sniggering at the code!

A few years ago I automated the treadmill in our guest room as a way of motivating
Tracy and I to keep fit. The treadmill sent us emails when we used it, and the
touch panels around the house showed how much we'd used it in the last week and
month. This worked really well for some time; until the point we realised if we both
agreed to stop using it on the same day then there would be no competition, no winner, no loser,
and neither us would feel bad.

Last winter the Red Hat video team came to my house to record some footage for both
internal and external use. On one of the internal videos they look at my home
automation system, point the camera at a wall tablet, and figure out that I'd not
used my treadmill in over two years. So there were really two options (1) remove the
year from the display so it would never look like we were slacking for more than
a year, or (2) find a way to get motivated again.

Recently we both started using Twitter, so it seemed like a natural progression to
hook the treadmill to twitter and have it publicly embarrass us for slacking
off.

We called it 'twedmill' ('tweadmill' perhaps is more correct, but just sounds like a
factory that weaves twead jackets).
Here is how it works:

The treadmill itself is pretty standard; it's from Trimline and has a fancy
computer. When I looked inside and saw a PIC I was tempted to interface direct
to the computer, but didn't really have the time to get around to that.
Although the treadmill does things like have a variable incline and measurement of heart
rate, all I really care about it making sure we were using it, for how long,
and how far we got.

Under a cover in the base are the PWM controllers, motors, and the belt
drive to the treadmill deck. The treadmill itself measures the belt speed
by having a single magnet on the wheel and a small sensor next to it, one
revolution giving one pulse. So to keep things simple I just hot-glued a
spare reed switch I had around so the same magnet would trigger it. The reed
switch happily copes with the treadmill even on top speed, so no real need
for anything more fancy.

I didn't have anything that could accurately measure the diameter of the roller, so
by counting pulses at various speeds and comparing to the onboard
display it worked out at 8122 pulses/revolutions per (uk) mile (so that's
about 198mm of travel per pulse, making the diameter of the
roller about 63mm).

I use a 1-wire network in the house to measure temperatures, watch the doorbell,
and control the central heating system, so I wanted to use the same system
to deal with the treadmill. So the reed switch connects to a DS2423
counter (Unfortunately it seems the DS2423 is discontinued now). The DS2423 was
only available in a surface-mount package, so I found some converters on ebay
to save having to design a PCB just for three components. The
DS2423 connects into a 1-wire hub in node0, then to a 1-wire USB adapter on our main
server, currently running Fedora 10.

The software used in based on the source code from 'digitemp'
as it includes
code in cnt1d.c to read the counter values. Every ten
seconds the jabber treadmill bot switches to the right network segment
on the 1-wire hub then polls the counter of the DS2423 to see
if the treadmill has moved. Once the treadmill has stopped moving for
a while the software stores the total distance travelled and time in
a database, sends an email, and uses the perl Net::Twitter module to
post a mesage to twitter. (It can also draw a graph showing speed over
time, but that turned out to be not very interesting)

For the future I'd quite like to hook directly into the
treadmill computer, perhaps giving two way control of the treadmill programs, as
well as recording the incline and heart rate. Another idea has been to use the
current treadmill speed to decide which music video to play next based on bpm (the tv is
connected to an old XBOX running XMBC so could easilly be remotely controlled to
switch videos). Or perhaps link it to google streets for a virtual jog through
some random town. Finally, you currently have to select who is using the
treadmill before (or very quickly after) using it using the touch panels in the
house; which seems like a good excuse to play with some RFID in our shoes, perhaps
also using that to select a playlist of music videos per person.

ZoneMinder is an amazing Linux video camera
security and surveillance application I use as part of my home automation
system. ZoneMinder prior to version 1.23.3 contains unescaped
PHP exec() calls which can allow an authorised remote user the ability to run
arbitrary code as the Apache httpd user (CVE-2008-1381)

This is really a moderate severity flaw because you need a remote attacker who
has the ability to start/stop/control ZoneMinder, and you really should protect
your ZoneMinder installation so you don't allow arbitrary people to control your
security system. (Although I think at least one distributor package of
ZoneMinder doesn't protect it by default, and you can find a few unprotected
ZoneMinder consoles using a web search).

I discovered this because when we went on holiday early in April I forgot to
turn down the heating in the house. Our heating system is controlled by
computer and you can change the settings locally by talking to a Jabber heating
bot (Figure 1). But remotely over the internet it's pretty locked down and the only thing
we can access is the installation of ZoneMinder. So without remote shell access,
and with an hour to spare at Heathrow waiting for the connecting flight to
Phoenix, I figured the easiest way to correct the temperature was to find a
security flaw in ZoneMinder and exploit it. The fallback plan was to explain to
our house-minder how to change it locally, but that didn't seem as much fun.

So I downloaded ZoneMinder and took a look at the source. ZoneMinder is a
mixture of C and PHP, and a few years ago I found a buffer overflow in one of
the C CGI scripts, but as I use Red Hat Enterprise Linux exploiting any new
buffer overflow with my ZoneMinder compiled as PIE definately wouldn't be
feasible with just an hours work. My PHP and Apache were up to date too. So I
focussed on the PHP scripts.

A quick grep of the PHP scripts packaged with ZoneMinder found a few cases where
the arguments passed to PHP exec() were not escaped. One of them was really
straightforward to exploit, and with a carefully crafted URL (and if you have
authorization to a ZoneMinder installation) you can run arbitrary shell code as
the Apache httpd user. So with the help of an inserted semicolon and one reverse shell
I had the ability to remotely turn down the heating, and was happy.

I notified the ZoneMinder author and the various vendors shortly after and
updates were released today (a patch is also
available)

Last month I read a blog entry from
hadess via Fedora Planet about hardware to let you run homebrew
applications on Nintendo DS. There is a ton of homebrew applications
available, but as of yet no jabber client.

My home automation system is all based around XMPP, with a standard Jabber
server to which all the home automation systems connect to share messages. I
wrote it like this so that it would be easy to just take some existing Jabber
client for a platform and be able to come up with a nice looking front end with
minimal effort.

I found Iksemel, a portable
C XML parser and protocol library that looked perfect, and it only
took a couple of hours to have it ported on the NDS, and a couple
more hours to get it working with PAlib for wifi. It's not a generic
Jabber chat client, but it wouldn't take too much work to make it into
one (although I didn't bother with encryption support so you won't be
able to use it with Google talk servers for example). Anyway, the code
might save someone a few hours, so I've made the source available.

I've included a copy of Iksemel, so if you want to build this yourself
all you need is a working development environment: devkitpro and PAlib. This
still needs some work, I need to integrate a library to handle displaying
images from the network (when the phone rings it can pop up the callers
picture or a streaming picture from one of the cameras when the doorbell
is pushed)

The biggest problem with my home-grown Home Automation system was that
I'm not a graphic designer. My displays all looked a little clunky, like
they'd come out of the 1980s. Guests only ever see the user interface
displayed on the tablets around the house, so I took some time over the
Easter holiday to make the user interface look a bit nicer.

The user interface is written in Perl/Tk and was designed to be
snappy even on the original Point 510 (100Mhz) tablets. I'd already
replaced these tablets around the house with Point 1600 tablets (most
picked up on ebay for about 50-100 pounds each) with the main
advantage that the Point 1600 can run at 800x600 in full-colour rather
than the 256 colours of the 510 in the same resolution.

I first looked around the web to see if there were any existing
Perl/Tk projects that had exciting graphic design I could base on, but
I didn't find anything very useful. In the end I decided to make
the UI look like a web site design proposed by a colleague at Red Hat
for some internal site that didn't get used.

Screenshots from the new design

Heat

The Heating interface lets you look at graphs of past readings for
any sensor or change the target temperature of the house.

Light

Actually we only have a couple of X10 lights in the house, and
we really only ever control the living room lights.

Weather

This is just screen-scraped from the BBC website and updated
every hour.

Cams

We use this screen to look at the security cameras as well
as some other Glasgow web cameras. The interface allows
multipart-jpeg streaming (compatible with ZoneMinder).

Phone

This actually displays a number of events such as the status
of the house alarm, capturing when the doorbell is pressed,
as well as popping up details of who calls us.

Screenshots of the original design

Software

I was previously using the Tk/TabBar module from Jarl to provide the
nice tab bars, and a bit of hacking gave the simplified tabbar (with
the advantage that the bar will still nicely wrap over two rows if
needed)

The rest of it was just messing around with frames and alignment and
creating the curved edges. I used the gimp to get a curve I was happy
with, then coverted it from a GIF to xpm with reduced colours. The
xpm was then coded into the application and simplified so that the
program can generate the right curves for any font size.

The Perl/Tk I used to create the headings is
available here and
running that program displays the following:

My home automation tablets use Perl/Tk as their user interface which
makes coding and prototyping really quick and easy and works on both
Linux and Windows platforms.
I use ZoneMinder for looking after the security cameras around the house and had
set up the tablets to be able to display a static image from any camera
on demand. But what I really wanted to do was to let the tablets display
a streaming image from the cameras.

ZoneMinder is able to stream to browsers by making use of the Netscape
server
push functionality. In response to a HTTP request, ZoneMinder
will send out a multipart replace header, then the current captured
frame as a jpeg image, followed by a boundary string, followed by the
next frame, and so on until you close the connection. It's perhaps
not as efficient as streaming via mpeg or some other streaming format,
but it's simple and lets you stream images to browsers without requiring
plugins.

So I wrote the quick Perl/Tk program below to test streaming from
ZoneMinder. It does make some horrible assumptions about the format
of the response, so if you want to use this with anything other than
ZoneMinder you'll need to edit it a bit. It also assumes that your
network is quite good between the client and ZoneMinder; the GUI will
become unresponsive if the network read blocks.

My first attempt ran out of memory after an hour -- I traced the memory
leak to Tk::Photo and it seems that you have to use the undocumented 'delete'
method on a Tk::Photo object otherwise you get a large memory leak. The
final version below seems to work okay though.

I use a Dallas 1-wire
network for temperature sensing and control around the house.
Ideally you run a single cable from the PC interface and attach
sensors along the wire, but I didn't think of that before the house
was wired. So instead I use a star network using the existing
cat5 networking to each room, with a one-wire hub from AAG
handling switching between the different spokes of the hub.

At the Home Automation server is a USB to 1-wire interface unit.
This interface connects directly to the one-wire hub. 6 outputs
from the hub go to various places around the house.

Output C6 has a ds18s20 temperature sensor plugged straight into
it, this provides the temperature of the home automation cupboard.

Output C5 goes to the lounge, which has a single ds18s20 temperature
sensor plugged straight into it, this provides the temperature of
the lounge which is used as the master control for the heating system.

Output C2 goes to the master bedroom, again with a single ds18s20
temperature sensor.

Output C1 goes to the garage, where a temperature
sensor is connected and poked out of the vent to get the outdoor
temperature, and on the same wire is a 1-wire switch used to
control the heating system.

The final output C4 goes to a hacked wireless doorbell. A one-wire
switch detects when the doorbell is activated. The one-wire hub
provides a 5v supply and so we use this to power the doorbell to save
on batteries.

The home automation sensor polls each device in turn to get a reading.
For short events (like a doorbell push) it monitors a latched register
which shows if the state of the input has changed since the last time
the device was polled. I'll write more about the software side of
this and give my source code in a later article.