Управление домашними электроприборами («умный дом») через чат бот на Raspberry Pi
В данном проекте запускаем своё iOS, Android или Web приложение, а также пишем (вернее, чуть дописываем) чат бот на питоне, который управляет розетками через радио модуль, подключенный к Raspberry Pi.В итоге, можем управлять домашними приборами и получать от них статусы удаленно и совместно с другими пользователями через общий чат.
Интересно?
А зачем? Вопрос «а зачем это нужно?» не всегда остро стоит для проектов из серии «умный дом» и всяческих Internet of Things, здесь часто тратится куча времени и денег на автоматизацию чего-то, что на практике удобнее переключать по старинке обычным настенным выключателем :-) Но при этом получаешь кучу удовольствия и полезного опыта в процессе и далее радуешься исправной работе механизма, который сделал сам.Но кроме вышеупомянутых удовольствий, мне кажется, управление домом и общение устройств через чат, конкретнее XMPP протокол, имеет право на жизнь по следующим причинам:
Человеческий язык — довольно легко заставить чат бот общаться с вами на человеческом языке, что довольно удобно, особенно для менее технических членов семьи. Также это позволяет в перспективе подключить голосовое управление. Универсальный удаленный доступ — к XMPP чат серверу можно подключаться откуда угодно и из любого Jabber совместимого IM клиента. Людям удобно, а как подключить устройства описано в данной статье. Удобное управление для всей семьи — подключите домашних в единый групповой чат, где сидят боты, отвечающие за дом или приборы в доме. Вы можете обсуждать свои семейные вопросы и одновременно управлять домом. Все видят, кто какие команды подал приборам, можно видеть их (ботов) ответы и отчеты, просмотреть предыдущую историю и т.п. Это удобно. Система независимых распределенных агентов. Каждый прибор или набор датчиков, которые имеют представительство (по сути, пользователя) в чате, соответственно являются независимыми агентами и могут общаться с другими приборами и быть управляемыми ими или вами напрямую. Единый сервер не обязателен. Можно поднять свой чат бот для каждого важного прибора или датчика, а также настроить главного бота с элементами AI, такой себе «дворецкий» или «majordomo», который будет всеми девайсами управлять, причем они будут общаться в доступном вам и другим членам семьи чате на понятном вам языке, так что вы всегда можете отследить что происходило или вмешаться в процесс. Реквизит Для данного мини-проекта нам потребуются следующие компоненты:1. Raspberri P.У меня модель B, заказал буквально за день до объявления о выходе B+, но в принципе, любая модель тут подойдет, главное смотрите, чтоб GPIO пины были совместимы с управляющим модулем, который вы выберете. Об этом ниже.Ну, а так, главное требование — запустить чат бот на питоне.
2. Аксессуары к вашему Pi.WiFi модуль, простые USB клавиатура и мышь, карточка SD памяти с дистрибутивом Raspbian, блок питания, по желанию — пластиковый корпус.Это стандарт для «малинки», но т.к. я покупал её впервые, специально под этот проект, то не знал, что WiFi и SD карта не входят в стандартный комплект, и пришлось дозаказывать, так что имейте в виду. Также для настройки вам потребуется монитор или телевизор с HDMI кабелем.
3. Управляющий модуль (RF transmitter) и розетки или другие приборы с приёмником (RF receiver).Здесь нужно сказать, что я пошел по быстрому или ленивому пути, и заказал готовый RF модуль для Pi и набор радиоуправляемых розеток от Energenie. В комплекте идет готовый RF передатчик, который подключается на GPIO пины вашей малинки. Кому этот путь не по душе, есть альтернативы, в инете куча гайдов о том, как к существующим радиоуправляемым приборам подобрать код и управлять ими через простой дешевый китайский RF передатчик. В качестве альтернативы можно через Pi управлять приборами непосредственно прямым проводным подключением с GPIO, а также через WiFi и по другим каналам.
Вот фото моего Energenie комплекта:
4. Чат-клиент.В данном туториале используется Q-municate, это мессенджер с открытым исходным кодом от нашей платформы QuickBlox, который можно скачать с github и забилдить под iOS, Android или запустить Web версию на десктоп и других платформах. Преимущество использования Q-municate в том, что вы можете кастомизировать интерфейс под себя и сделать своё собственное приложение, например, только для своей семьи.Но это совершенно не обязательно. Вы можете использовать любой Jabber/XMPP совместимый клиент, например Adium.
Итак, начнем.
Устанавливаем дистрибутивы / dependencies для Raspbian Логинимся на малинку и ставим следующие вещи под рутом: apt-get install python-dev pip install sleekxmpp pip install dnspython pip install pyasn1 pyasn1-modules apt-get install python-rpi.gpio Нам собственно нужен sleekxmpp, это базовый проект для чат бота, а остальное решает вопросы с различными зависимостями для этого проекта. Ну и плюс python-rpi.gpio позволит контролировать GPIO пины малинки из нашего питон скрипта.Подключаем и проверяем модуль радиоуправления Если вы используете другой модуль, не от Energenie, то эту часть вам придется исследовать самостоятельно.При использовании же готового Pi-mote модуля всё просто и хорошо описано в официальной инструкции от производителя: energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf
Лично я потратил непозволительно много времени пытаясь определить, работает ли мой комплект радиоуправляемых розеток, меряя напряжение на малинке, пробуя неофициальные скрипты и т.п., так как розетки Energenie почему-то никак не хотели управляться скриптом, как это описано у производителя и на нескольких блогах. Не сразу дошло еще раз заглянуть в мануал и прочитать на этот раз внимательно, а там английским по белому говорится, что сокеты нужно запустить сначала в обучающем режиме. Логично. В своё оправдание могу только сказать, что проект делал рано по утрам в выходные, пока семья спит, видимо, сказался недосып :-)
Итак, обучаем. Согласно инструкции, запускаем скрипт
sudo python ENER002.py вставляем розетки в розетки) и если лампочки на них не мигают, то переводим в режим обучения нажатием кнопки выключения в течение 5 секунд. Лампочки замигали, нажимаем «Enter» на клавиатуре чтобы подать сигнал из скрипта и видим быстрое мигание лампочки, это значит что обучение прошло успешно. Повторяем то же самое с остальными розетками. Один Pi-mote модуль может подавать 4 разных кода, т.е. управлять можно 4 разными наборами Energenie розеток, при этом никто не мешает использовать один код для нескольких розеток одновременно.Поднимаем чат сервер Нам нужен XMPP / Jabber совместимый чат сервер с возможностью создания MUC (группового чата или чат комнаты) в нём, чтобы подключить туда наш чат бот и человеков-пользователей.В принципе, на Pi можно поднять свой чат сервер, например вот здесь http://box.matto.nl/raspberryjabberd.html описывается установка ejabberd на Raspberri Pi.
В данной статье мы опять идем по пути наименьшего сопротивления и используем готовый бесплатный чат сервер от QuickBlox. Вам нужно просто создать аккаунт, чтобы получить свой собственный чат сервер и веб админку к нему.
Шаги ниже описывают регистрацию и заодно создание пользователя для нашего чат бота и MUC комнаты для общения.
1. Регистрируемся на http://quickblox.com/signup/ или логинимся через GitHub / Google
2. Создаем приложение в админке.
3. Создаем пользователя для нашего чат бота (Users → Add new user)
4. Создаем MUC комнату для общения (Chat → New dialog)
Всё, ваш собственный XMPP чат сервер готов к приёму граждан и ботов, 24 часа в сутки, без перерывов на обед.
Пишем и настраиваем чат бот Мы уже установили библиотеку SleekXMPP, которая реализует XMPPшный чат бот на питоне.На сайте проекта есть хороший пример по MUC чат боту: http://sleekxmpp.com/getting_started/muc.htmlа исходник можно взять здесь: https://github.com/fritzy/SleekXMPP/blob/develop/examples/muc.pyДальше нам нужно взять и модифицировать это под свои нужды.Если вы тоже используете Energenie для управляемых розеток и QuickBlox для чат сервера, то вы можете взять мой готовый скрипт здесь: https://github.com/QuickBlox/sample-powerbot-python-rpi.Вам нужно будет только поменять credentials в начале скрипта, прописав туда свои ключи приложения и пользователя (того, что мы создали выше).
Ниже мы пройдемся более детально по внесённым изменениям, но вкратце, что было сделано (заранее прошу прощения за уровень питон кода — давно не программист и тем более не питонщик — буду благодарен за любые улучшения и пулл реквесты):
1. Добавлено авто-присоединение по приглашению в другие чат комнаты.
2. Подправлена совместимость с QuickBlox и Q-municate (мелочи типа формата названия чат комнат и т.п.)
3. Добавлен собственно парсинг команд для управления приборами — в нашем случае это «lamp on», «lamp off», «all on» и «all off» — и вызов функций switch_on / switch_off из питон модуля energenie, который уже отдает команды на плату радиопередатчика через GPIO.Кто работает напрямую с GPIO, посмотрите в energenie.py как реализована работа с GPIO.
Авто-присоединение в другие чат комнаты Опциональная фича, но лично мне этого не хватало, например, когда в мессенджере у вас в друзьях висит этот бот-дворецкий и вы можете создавать новые чаты и приглашать его туда. Без этого работать будет, но тогда бот будет привязан к тому чату, в который вы его запустили.Как реализовать авто-присоединение — парсим станзы входящих XML сообщений, т.к. нам обязательно прийдет сообщение о том, что создан такой-то MUC чат, если данный пользователь был туда приглашен.
В нашем случае мы используем платформу QuickBlox и конкретное приложение Q-municate, в нём приглашение в новый групповой чат выглядит примерно так:
RECV:
chmod +x powerbot.py Код реализации представлен ниже: 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 self.send_message (mto=msg['from'].bare, mbody=«Thank you for your kind invitation, joining your new room now!», mtype='groupchat') Приветствие + инструкции Определяем кодовое слово, в данном случае «powerbot», и выдаем в ответ приветствие и подсказку о том, как пользоваться / общаться с нашим ботом.Проверка «if msg['from'] != self.nick» нужна чтобы бот не реагировал на сообщения от себя самого. # # 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'], mtype='groupchat') self.copy_dialog_id (msg, reply_test_message) reply_test_message.send () print «Sent help text:» + str (reply_test_message) Включение / выключение лампы и других приборов Отслеживаем команду «lamp on» (включить лампу), если команда получена, то включаем розетку switch_on (lampSocket) и отчитываемся о выполнении. # # Handle «lamp on» command # if msg['mucnick'] != self.nick and «lamp on» in msg['body']: switch_on (lampSocket) confirmation_message = self.make_message (mto=msg['from'].bare, mbody=«Lamp has been switched on, %s.» % msg['mucnick'], mtype='groupchat') self.copy_dialog_id (msg, confirmation_message) confirmation_message.send () print «Lamp switched on, sent confirmation:» + str (confirmation_message) Аналогичным образом реализованы «lamp off», «all on» и «all off» (последние отвечают за включение или выключение всех управляемых розеток).Запускаем чат бот Из bash на малинке выполняем нехитрую команду: sudo python powerbot.py -d -r <адрес начальной MUC комнаты> Sudo нужно для доступа к GPIO. Если вы использовали QuickBlox, то в качестве адреса MUC комнаты просто скопируйте JID адрес из таблички Chat Dialogs.В результате на экране появятся логи аутентификации и обмена XMPP статусами с сервером:
Всё, бот готов и ждет ваших указаний в чат-комнате.
Кстати, вы могли обратить внимание, что функции реакции на команды продублированы одновременно в
def message (self, msg): и def muc_message (self, msg): первый блок обрабатывает приватные сообщения 1:1, а второй — групповые.То есть управлять ботом можно и в приватном чате, хотя на мой взгляд, это менее интересно.Собираем чат клиент под iOS (варианты: Android, Web) Как я писал выше, можно общаться с ботом через любой Jabber / XMPP — совместимый чат клиент.Мы легких путей не ищем, поэтому собираем своё приложение — клиент для управления ботом ну и заодно для общения с домашними и друзьями.Свой собственный мессенджер с ботом и групповыми чатами :-)Однако, как вы увидите, мы здесь тоже идем по быстрому и ленивому пути и берем готовый open-source проект нашей собственно разработки, который называется Q-municate.
1. Тянем с гита проект для соответствующей платформы: iOS: bitbucket.org/quickblox/qmunicate-iosAndroid: github.com/QuickBlox/q-municate-androidWeb: github.com/QuickBlox/q-municate-web
2. Открываем в IDE.
3. Правим креденшелы — меняем стандартные константы с ключами приложения на скопированные из админки QuickBlox. В iOS это меняется в AppDelegate.m, в Android в Consts.java.
4. Компилируем, билдуем на девайс.По желанию кастомизируем интерфейс и прочее, тут более подробный мануал.
5. PROFIT!!!
Демонстрация Скрины: свой билд Q-municate я назвал гордо «Q-Power»
находим бота в френдах или групповом чате
общаемся с ботом
Видео управления лампой через чат:
[embedded content]
Спасибо за внимание, надеюсь пригодится, а еще лучше если данный «proof of concept» сподвигнет кого-то реализовать идею до конца, и микроволновка вдруг заговорит с тостером, а давать им всем команды будет жена голосом через вашу домашнюю Siri:-)
Успехов!