Home appliance management (“smart home”) via chat bot on Raspberry Pi

Published on October 07, 2014

Home appliance management (“smart home”) via chat bot on Raspberry Pi

  • Tutorial
In this project, we launch our iOS, Android or Web application, and also write (or rather, add a little) a chat bot on python that controls sockets through a radio module connected to the Raspberry Pi.

As a result, we can manage home appliances and receive statuses from them remotely and jointly with other users through a common chat.


What for?

The question “why is this necessary?” Is not always acute for projects from the “smart home” series and all sorts of Internet of Things, a lot of time and money is often spent here to automate something that, in practice, is more convenient to switch the old-fashioned way with an ordinary wall switch: -) But at the same time you get a lot of pleasure and useful experience in the process and then you rejoice at the proper operation of the mechanism that he made.

But besides the aforementioned pleasures, it seems to me that managing a home and communicating via chat, specifically the XMPP protocol, has the right to life for the following reasons:

  • Human language - it’s quite easy to make the chat bot communicate with you in human language, which is quite convenient, especially for less technical family members. It also allows you to connect voice control in the future.
  • Universal remote access - you can connect to the XMPP chat server from anywhere and from any Jabber compatible IM client. It’s convenient for people, and how to connect devices is described in this article.
  • Convenient management for the whole family - connect your pets to a single group chat, where the bots are in charge of the house or appliances in the house. You can discuss your family issues while managing your home. Everyone sees who sent what commands to the devices, you can see their (bots) answers and reports, view the previous story, etc. It's comfortable.
  • A system of independent distributed agents . Each device or set of sensors that have a representative (in fact, a user) in the chat, respectively, are independent agents and can communicate with other devices and be controlled by them or you directly. A single server is optional. You can raise your chat bot for each important device or sensor, as well as configure the main bot with AI elements, such as a “butler” or “majordomo”, which will manage all devices, and they will chat in a chat accessible to you and other family members on language that you understand, so you can always track what happened or intervene in the process.


For this mini-project, we need the following components:

1. Raspberri P.
I have a model B, I ordered it just a day before the announcement of the release of B +, but in principle, any model is suitable here, the main thing is to see that the GPIO pins are compatible with the control module which you choose. About it below.
Well, and so, the main requirement is to start a chat bot on python.

2. Accessories for your Pi.
WiFi module, simple USB keyboard and mouse, SD memory card with Raspbian distribution, power supply, optionally a plastic case.
This is the standard for raspberries, but because I bought it for the first time, especially for this project, I did not know that WiFi and SD cards are not included in the standard package, and I had to reorder, so keep in mind. You will also need a monitor or TV with an HDMI cable to configure.

3. The control module (RF transmitter) and sockets or other devices with a receiver (RF receiver).
Here I must say that I went on a fast or lazy path, and ordered a ready-made RF module for Pi and a set of radio-controlled sockets from Energenie. The kit comes with a ready-made RF transmitter that connects to the GPIO pins of your raspberry. There are alternatives to whoever likes this path, there are a lot of guides on the Internet on how to pick up a code for existing radio-controlled devices and control them through a simple cheap Chinese RF transmitter. Alternatively, you can control the devices through Pi directly with a direct wired connection with GPIO, as well as via WiFi and other channels.

Here is a photo of my Energenie kit:

4. Chat client.
This tutorial uses Q-municate., this is an open source messenger from our QuickBlox platform, which can be downloaded from github and build under iOS, Android or run the Web version on desktop and other platforms. The advantage of using Q-municate is that you can customize the interface for yourself and make your own application, for example, only for your family.
But this is absolutely not necessary. You can use any Jabber / XMPP compatible client, for example Adium.

So, let's begin.

Install / dependencies distributions for Raspbian

We login to the raspberry and put the following things under the root:
apt-get install python-dev
pip install sleekxmpp
pip install dnspython
pip install pyasn1 pyasn1-modules
apt-get install python-rpi.gpio

We actually need sleekxmpp, this is a basic project for a chat bot, and the rest solves issues with various dependencies for this project. Well, plus python-rpi.gpio will allow you to control the GPIO raspberry pins from our python script.

We connect and check the radio control module

If you use another module, not from Energenie, then you will have to examine this part yourself.

When using the ready-made Pi-mote module, everything is simple and well described in the official instructions from the manufacturer: energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf

Personally, I spent an unacceptably long time trying to determine if my set of radio-controlled sockets is working, measuring the voltage on a raspberry, trying unofficial scripts, etc., because for some reason Energenie sockets did not want to be controlled by a script, as described by the manufacturer and several blogs. It did not immediately come to look into the manual again and read carefully this time, and there it is said in English in white that the sockets must be started first in the training mode. Is logical. In my defense, I can only say that the project was done early in the mornings at the weekend, while the family was sleeping, apparently, lack of sleep affected :-)

So, we are training. According to the instructions, run the script

sudo python ENER002.py 

insert the sockets into sockets) and if the lights on them do not blink, then switch to the learning mode by pressing the power button for 5 seconds. The lights blinked, press “Enter” on the keyboard to give a signal from the script, and we see a quick blinking of the light, which means that the training was successful. Repeat the same with the other outlets. One Pi-mote module can serve 4 different codes, i.e. You can control 4 different sets of Energenie outlets, while no one bothers to use the same code for several outlets at the same time.

Raise the chat server

We need an XMPP / Jabber compatible chat server with the ability to create a MUC (group chat or chat room) in it to connect our chat bot and human users there.

In principle, on Pi you can raise your chat server, for example, here http://box.matto.nl/raspberryjabberd.html describes how to install ejabberd on a Raspberri Pi.

In this article, we again follow the path of least resistance and use the ready-made free chat server from QuickBlox . You just need to create an account to get your own chat server and a web admin panel to it.

The steps below describe the registration and at the same time creating a user for our chat bot and MUC chat room.

1. Register at http://quickblox.com/signup/or log in via GitHub / Google

2. Create an application in the admin panel.

3. Create a user for our chat bot (Users -> Add new user)

4. Create a MUC chat room (Chat -> New dialog)

Everything, your own XMPP chat server is ready to receive citizens and bots, 24 hours a day, without lunch breaks.

We write and configure the chat bot

We have already installed the SleekXMPP library, which implements the XMPP chat python chat bot.
The project website has a good example of a MUC chat bot: http://sleekxmpp.com/getting_started/muc.html
and the source can be taken here: https://github.com/fritzy/SleekXMPP/blob/develop/examples/muc. py

Next we need to take and modify this to fit our needs.
If you also use Energenie for managed outlets and QuickBlox for the chat server, then you can take my ready-made script here: https://github.com/QuickBlox/sample-powerbot-python-rpi .
You will only need to change the credentials at the beginning of the script, registering there your application and user keys (of what we created above).

Below we will go into more detail on the changes made, but briefly what has been done (I apologize in advance for the level of python code - I have not been a programmer for a long time and especially not a python - I will be grateful for any improvements and pull requests):

1. Added auto-join by an invitation to other chat rooms.

2. Fixed compatibility with QuickBlox and Q-municate (little things like chat room name format, etc.)

3. The actual parsing of commands for controlling devices has been added - in our case it is “lamp on”, “lamp off”, “all on "And" all off "- and calling the switch_on / switch_off functions from the python of the energenie module, which already sends commands to the radio transmitter board via GPIO.
Who works directly with GPIO, look at energenie.py how GPIO work is implemented.

Auto join other chat rooms

An optional feature, but I personally didn’t have it, for example, when this bot-butler hangs in your friends' messenger and you can create new chats and invite him there. Without this, it will work, but then the bot will be tied to the chat in which you launched it.

How to implement auto-attachment - parsim stanza of incoming XML messages, because we will definitely get a message that such a MUC chat was created if this user was invited there.

In our case, we use the QuickBlox platform and the specific Q-municate application, in it the invitation to a new group chat looks something like this:
RECV: <message to="1265350-7232@chat.quickblox.com" from="1234040-7232@chat.quickblox.com/098CA696-A60A-480D-B744-BE7DFC4FE6D3" id="1404538064.385079" type="chat"><body>Taras Filatov created new chat</body><extraParams><_id>53b78c0c535c12798d005055</_id><occupants_ids>1234040,1258466,1265350</occupants_ids><type>2</type><date_sent>1404538064</date_sent><name>Yanus Poluektovich, Sergey  Fedunets</name><xmpp_room_jid>7232_53b78c0c535c12798d005055@muc.chat.quickblox.com</xmpp_room_jid><notification_type>1</notification_type></extraParams></message>

We track the phrase “created new chat” in XMPP stations, and if it occurs, then parse from there xmpp_room_jid, this will be the id of the newly created room.
Next, start the process with the same script.
Keep in mind that in order for this to work, you need to make the script executable:

chmod +x powerbot.py

The implementation code is presented below:

        if msg['mucnick'] != self.nick and "Create new chat" in msg['body']:
            from bs4 import BeautifulSoup
            y = BeautifulSoup(str(msg))
            roomToJoin = y.xmpp_room_jid.string
            print ("Got an invite to join room")
            botId = subprocess.Popen([selfPath + " -d -j " + qbChatLogin + " -r " + str(roomToJoin) + " -n " + qbChatNick + " -p " + qbUserPass], shell=True)
            print "spawned new bot ID="
            print botId
                          mbody="Thank you for your kind invitation, joining your new room now!",

Greetings + instructions

We determine the code word, in this case “powerbot”, and give back a greeting and a hint about how to use / communicate with our bot.
The check “if msg ['from']! = Self.nick” is needed so that the bot does not respond to messages from itself.

        # Reply to help request (any message containing "powerbot" in it)
        if msg['mucnick'] != self.nick and "powerbot" in msg['body']:
            reply_test_message = self.make_message(mto=msg['from'].bare,
                      mbody="Powerbot is greeting you, %s! Usage: [powerbot] lamp [on|off] to control socket 1, [powerbot] all [on:off] to control all sockets. Example: 'lamp on' switched socket 1 on." % msg['mucnick'],
            self.copy_dialog_id(msg, reply_test_message)
            print "Sent help text: " + str(reply_test_message)

Turn on / off the lamp and other devices

We track the “lamp on” command (if the command is received, then turn on the switch_on socket (lampSocket) and report on the implementation.

        # Handle "lamp on" command
        if msg['mucnick'] != self.nick and "lamp on" in msg['body']:
            confirmation_message = self.make_message(mto=msg['from'].bare,
                                                   mbody="Lamp has been switched on, %s." % msg['mucnick'],
            self.copy_dialog_id(msg, confirmation_message)
            print "Lamp switched on, sent confirmation: " + str(confirmation_message)

Similarly implemented “lamp off”, “all on” and “all off” (the latter are responsible for turning on or off all controlled outlets).

We start a chat bot

From bash on malink we execute a simple command:

sudo python powerbot.py -d -r <адрес начальной MUC комнаты>

Sudo is needed to access the GPIO. If you used QuickBlox, then just copy the JID address from the Chat Dialogs plate as the MUC address of the room.

As a result, the logs of authentication and XMPP status exchange with the server will appear on the screen:

That's it, the bot is ready and waiting for your instructions in the chat room.

By the way, you may have noticed that the response functions to commands are duplicated simultaneously in
def message(self, msg):

def muc_message(self, msg):

the first block processes private messages 1: 1, and the second - group messages.
That is, you can manage the bot in a private chat, although in my opinion, this is less interesting.

We collect the chat client for iOS (options: Android, Web)

As I wrote above, you can communicate with the bot through any Jabber / XMPP - compatible chat client.
We are not looking for easy ways, so we are building our application - a client for managing a bot, and at the same time for communicating with family and friends.
Our own messenger with a bot and group chats :-)

However, as you will see, here we are also following a quick and lazy path and we take a ready-made open-source project of our own development,
which is called Q-municate.

1. Pull the project for the appropriate platform from gita:
iOS: bitbucket.org/quickblox/qmunicate-ios
Android: github.com/QuickBlox/q-municate-android
Web: github.com/QuickBlox/q-municate-web

2. Open in the IDE.

3. Edit the credits - change the standard constants with application keys to the ones copied from the QuickBlox admin panel. In iOS, this changes in AppDelegate.m, in Android in Consts.java.

4. Compile, build on the device.
At will, we customize the interface and more, here is a more detailed manual .

5. PROFIT !!!



I called my Q-municate proudly “Q-Power”,

we find the bot in friends or group chat, we

communicate with the bot

Video lamp control via chat:

Thank you for your attention, I hope it will come in handy, and even better if this “proof of concept” encourages someone to implement the idea to the end, and the microwave suddenly speaks with the toaster, and the wife gives voice to all of them through your home Siri :-)