Интерфейс умный дом. Концепт: Система управления «умным» домом с дополненной реальностью SmartShell. Каким он должен быть

Повествование с краткими техническими отступлениями.

Как все начиналось

История эта началась почти полтора года назад. К нам пришел заказчик с «проектом мечты».
Заказ звучал коротко и просто: изменить дизайн UI текущей системы умного дома.
Взглянув на систему, было видно типичного представителя умного дома, каких сейчас множество, вот она в старом дизайне.
А именно: унылые иконки взятые из сети, непродуманная логика экранов, не эргономичное использование пространства маленького разрешения, гламурные градиентные кнопки, и датчики на плане этажа сделанные так, как получилось у программиста.


Но архитектура проекта представляла из себя довольно грамотное решение. Был сервер управления датчиками и анализа данных, представляющий из себя маленькую коробочку, к которому можно было подключиться тремя способами:

  • С домашнего компьютера через браузер (как к роутеру) в административный интерфейс - для настройки всего и вся
  • С сенсорной панели при входе в дом - для управления сигнализацией, сценариями, камерами и датчиками (с нее нам было и предложено начать)
  • С мобильных устройств - для управления домом из любого места (в первом варианте через туже админку)

Переговорив с заказчиком, решено было делать интерфейс в стиле Windows 8, хотя сама она тогда еще не вышла, были лишь многочисленные скриншоты в сети. Опустим подробности такого решения, скажу лишь, что оно было принято единогласно и мы приступили к работе.
Тут стоит упомянуть, что у нас к тому времени был некоторый опыт проектирования интерфейсов близких по духу: панель управления яхтами (они достойны отдельных статей, но там NDA жесткое), бортовой компьютер авто и пяток сенсорных киосков.

Идея

Тема проектировки системы умного дома давно будоражила мое воображение. Решения, что существуют на рынке, и близко не приближаются к тому, что я могу назвать «Умным».

Рассмотрим пример

Стемнело. Вам нужно включить свет в комнате. Ваши действия?
Как это происходит обычно - вы встаете и включаете свет.
По версии многих разработчиков систем автоматизации - вы берете пульт и включаете свет.
Часто тут не видят банальных проблем. Во-первых, пульта рядом может и не быть, надо-таки встать, чтобы его найти, во-вторых, не забываем, что большинство таких устройств сейчас с сенсорным экраном, это означает, что пульт нужно еще и включить. Новая мода - делать пульт с планшета или телефона (отдельное приложение), что еще больше усложняет задачу:
Встать и найти устройство - > Включить или разблокировать экран -> Запустить приложение - > Найти нужный датчик - > Профит.
Не проще ли встать и включить выключатель?
Умный дом в моем понимании - должен сам включить свет тогда, когда это вам необходимо, при этом учесть бодрствуете вы или отдыхаете, время года, количество людей в комнате, ваше местоположение в комнате и еще кучу факторов, основываясь на предыдущие ваши решения в подобных ситуациях, предугадывая ваши желания. Иначе, дом этот сложно назвать «умным».
Пульт же - должен использоваться лишь частных случаях и не должен являться основным элементом управления домом. По-настоящему, «Умным» домом" вообще не нужно управлять - он все сделает сам.

Но до таких систем еще далеко, можно сказать, реализовать это сегодня невозможно, поэтому будем улучшать то, что можем, а именно, тот самый пульт.

Главную проблему этих решений проще показать знакомой хабру картинкой:

Да, почти все подобные системы - это пульты управления ядерным реактором, в которых сложно порой разобраться даже продвинутому пользователю.
Разработчики почему-то стараются поместить на экран как можно больше элементов, как можно больше возможностей и, как следствие, как можно больше проблем UX.

Так в чем же идея?

Убрать с глаз долой все лишнее, абсолютно все.
Если я хочу просто выключить свет в спальне, зачем мне видеть датчики управления водяными клапанами на кухне?
Если мне хочется закрыть все окна в доме, то я хочу делать это одной кнопкой, а не тыкать в каждый датчик по отдельности.
Если я ставлю дом на сигнализацию и в доме никого нет - это значит, что свет везде должен быть погашен, температура понижена, окна закрыты, включено видеонаблюдение. И все это должно произойти без моего участия!

Одно кольцо, чтобы править всеми Одна кнопка - «Сделать хорошо».

Лучший интерфейс тот - которого вы не видите, на который вы не обращаете внимание во время работы, который делает все за вас, либо же вы управляете им на подсознательном уровне, потому что:
а) вы привыкли так
б) это очевидно
Обращаете ли вы внимание на то, где находиться кнопка Play на Youtube? Где кнопка закрытия окна браузера? Или где поле поиска в Google?
А введет ли вас в ступор сотня датчиков на одном экране системы умного дома?
Верно, все, что на самом деле требуется от подобных систем - решить одну какую-то конкретную задачу (как Play в плеере или Find в поиске). Поэтому нет смысла выводить все возможное управление на экран.

Не такая простая задача на самом деле.

Первый прототип.

От заказчика мы получили его видение примерно так:

Посмотрели, подумали, и единственное, что использовали из его материалов, это спецификации датчиков и команд (сценариев пользователя)
Нас загоняло в рамки несколько моментов:

  • В сенсорной панели не было поддержки MultiTouch и она имела разрешение 1024*768 и 1024*600
  • Metro интерфейс был новым и не было возможности пощупать его на планшетах (8-ка еще не вышла). Хотя у нас был телефон на WP7, что давало некоторое представление.
  • Заказчик некоторые моменты в системе не мог изменить (железные ограничения, удорожание системы, личные хотения, и тп)

В целом сделать дизайн таких экранов как: главное меню, видеонаблюдение и интерком, погода за бортом, уведомления системы и подобных - не составило проблем, да и незачем об этом рассказывать, это была 1-я версия, дальше будет интереснее.
Проблемным был лишь основной экран управления датчиками. О нем и напишу.

План дома

Вот картинка типичного экрана управления датчиками с планом дома взятая из интернета:

Скажите, многие ли из вас понимают, что нарисовано на этом плане?
А поймет ли этот план ваш ребенок? А ваша бабушка? А друг, зашедший на чаек, сориентируется?
Думаю проблема понятна.

План должен быть читаем всеми и сразу. Для этого на нем должен быть виден именно ваш дом, с вашим цветом стен и основной мебелью:

А в идеале, план еще должен быть всегда позиционирован относительно сторон света.
Такое решение дороже, да и перестановка мебели сделает план не точным, но тут в любом случае - компромисс. Впрочем, ничто не мешает включить в проект любой план, либо же и вовсе без него (такое решение нами тоже было спроектировано).
Кстати, в первых версиях для премиум класса хотели сделать план в 3D, но решение сильно дороже, да и лишнее это, перспективы - вполне достаточно.

Датчики

Самая большая проблема - визуальное представления датчиков управления на плане решилась быстрее чем ожидалось. Как сейчас помню, мы с дизайнером сидели и рисовали на бумаге WireFrames будущей системы, и решение пришло само собой:

Ниже я прикрепил видео, где видно как это работает.

Одна кнопка

«Ну и где же тут одна кнопка?» - спросите вы.
А вот где:
«Одна кнопка» - это условность, под этим я понимаю одну функцию - самую важную и вынесенную на передний план.
Разрешение у нас маленькое, показывать на нем красочный план и утыкав его датчиками «по самое не хочу» - плохая идея.
Стоит вспомнить, что сейчас я описываю создание стационарной версии пульта (т.е. это монитор вмонтированный в стену).
Основные сценарии типового использования этой панели таковы:

  • Человек открывает входную дверь - > активируется панель и предупреждает нас, что нужно отключить сигнализацию - > вводится пароль - > активируются сценарии заданные для этого дома.
  • то же самое при выходе из дома - ставим на сигнализацию
  • Если кто-то звонит в дверь - смотрим кто, через интерком, который показывается поверх любого экрана при звонке с улицы и открываем дверь.
  • Активация пользовательских сценариев - например режим «Ночь», когда двери и окна запираются, включается видеонаблюдение, снижается температура и пр.

Управление отдельными датчиками с этой панели не очень-то удобно (ну сами посудите, вы будете настраивать яркость света в спальне, находясь в коридоре?)
Управление возможно, если панели встроены по всему дому.
Но, по словам заказчика, функция эта там необходима, нужно делать.

Решение

При входе на экран, пользователь видит только план дома. Датчики видны в виде очень маленьких точек (для того, чтобы знать где они).
Кроме возможности переключить этаж у пользователя всего 2 варианта:
1) Активировать панель опций, что позволит, например, вывести все термостаты в доме на план и настроить температуру как не предусмотренно сценариями, или, например, активировать розетки в гараже.

2) Увеличить план. Чем больше увеличиваем - тем больше датчиков превращается из маленькой точки в полноценный контрол управления, датчики появляются в зависимости от приоритета. Тем самым не загромождая собой пространство.

Т.е. пользователь всегда видит только то, что ему необходимо.

Интеграция

Решение заказчика было на WPF, а интеграция дизайна в XAML, это основная моя специализация. Поэтому мы не только «рисовали картинки», но и реализовывали дизайн на практике.
О том, как мы делали контролы и их XAML, все это анимировали и привязывали к плану дома, можно написать отдельную большую статью, но чем меньше знают конкуренты, тем более ценны мы как специалисты. Да и нет особого смысла описывать решение стационарного пульта, т.к. далее речь пойдет о планшетной версии.

Кому интересен не только экран управления датчиками, но и все остальное, могут посмотреть итоговый результат в картинках
Или на видео:

В сумме на проектирование, дизайн и его реализацию в демо приложение, которое в дальнейшем ушло программистам заказчика уже непосредственно для привязки железа и логики, у нас ушло около 5 месяцев.
И, как обычно это бывает, сделав проект - всегда хочешь его переделать, потому что уже видишь, как сделать его лучше, его недостатки и слабые места, а слабых мест тут было много.

Пока я делал XAML, вышла Windows developer preview, и я тут же поспешил ее потрогать на десктопе и на своем планшете (Aser Iconia W500). Так же вышли официальные Guidlines, что позволило взглянуть на Metro UI по-новому.

Часть 2.

Все что мы сделали - фигня

Заказчик был очень доволен, особенно когда мы презентовали рабочую демку. Можно сказать, счастью его не было предела. Я видел недостатки проекта, но в тоже время знал, что довести до идеала его можно лишь работая над ним много времени в паре с командой хороших программистов, но это не имело значения на данном этапе развития продукта.
Заказчик, как и я, уже посмотрел новую Windows 8, и мы оба считали, что она очень хороша. Поэтому на мое предложение: «А давайте сделаем версию для планшета?», отреагировал очень положительно. Я предложил не менять встраиваемую в стену систему, т.к. она не поддерживала MultiTouch, ставить туда восьмерку не было смысла. Её редизайн оставили до лучших времен, сосредоточившись на Metro/Windows store приложении (именно Metro, т.к. это позволит распространять демку в маркете для привлечения клиентов).
К сожалению, бюджет у заказчика оказался не резиновый, но я согласился, по сути версию для Windows 8 мы подарили. Отчасти это было необходимо, у нас была очень хорошая работа в портфолио еще до релиза восьмерки.

Второй прототип.

Через пару недель мой дизайнер предоставил мне свое видение планшетной версии продукта:


Полную версию дизайна можно

Я был немного расстроен, дизайн был далек от того что было нужно, я попытался объяснить ошибки, но нельзя научиться плавать не залезая в воду, дизайнер не мог дать мне то, что я хотел, потому что тогда у него было слишком мало опыта общения с Windows 8.

Поэтому было решено все переделать, но вести работу над дизайном совместно со мной, делая все сразу в XAML.
Это решит проблему нехватки скилов по Guidlines у дизайнера, а мне, как разработчику, не даст испортить картинку.

Дизайн V2 и одновременная интеграция

Честно сказать, это было чертовски сложно. Я готов был убить разработчиков Blend 5, ибо по сравнению с 4-й версией, это было глючное, неработоспособное, постоянно вылетающее чудовище. Сейчас дело обстоит получше, но некоторых моментов не хватает.
Меня спасла VS 2012, в нее частично включили функционал бленда для управления стилями.
Новый XAML - это тема отдельного разговора, половины старых классов нет, дефолтные стили никуда не годятся, триггеры удалили - оставив только не богоугодные Visual States. Так же пришлось переписать проект с нуля когда Win 8 обновилась до Relize Preview, но те изменения были в лучшую сторону.

Новая концепция

Новое устройство - новый подход. Пришлось пересмотреть идею стартового экрана, теперь он был не нужен, а вся навигация выносилась в верхний AppBar.
Долой все кнопки с экрана: Zoom - жестом, у нас же полноценный MultiTouch, все управление датчиками - в нижний AppBar.
Теперь приложение стартует сразу с показа плана дома (в идеале оно должно отслеживать в какой комнате находиться пользователь и сразу ее немного увеличивать позиционируя по центру).

Открываем приложение:

Делаем жест Zoom (или мышкой CTRL+колёсико):

Или достаем AppBar:

Контролы

Контролы датчиков пришлось переписать с нуля, и сделать их нативными с нормальной поддержкой жестов Windows 8.
Было учтено, что теперь у нас управление 2-мя способами, пальцами и мышью.
Так же был вылизан внешний вид датчиков, стало более стильно:


Особенно наповал сразила скорость работы приложения. Производительность в Windows8 приложениях на порядки выше WPF. Я боялся, что планшет не осилит систему, но все просто летает. Microsoft превзошли самих себя, теперь не имеет значения насколько сложен XAML, все будет работать быстро. Если в WPF приходилось делать самопальные алгоритмы кеширования экранов для быстрой анимации, думать над сложностью ветвления XAML, оптимизировать количество элементов в дереве контрола, то в восьмерке, это просто не имеет значения, анимация любой сложности и любого количества объектов всегда плавная.

Вариант без плана


Тут были не нужны датчики с поддержкой жестов, не нужно было экономить пространство. Получилось конечно не так эффектно, но хорошо.

Сценарии

Управление датчиками, это конечно хорошо, но, как я уже писал, базовые операции с ними лучше автоматизировать.
Для этого в административном интерфейсе есть базовые предустановки сценариев и возможность создания своих.

На планшете это выглядит так:

Одна кнопка

От этой концепции мы не отходили с самого начала.
Часто задают вопрос: «А где тут работы на полгода?»
И это я воспринимаю как похвалу. Это значит, я добился того - чего хотел. Пользователь просто не видит, что функционал приложения - довольно большой, ведь видно только то, что нужно на данный момент. Данные и необходимые экраны сами показываются пользователю, а не он ищет их. Интерфейс понятный с первых минут, не пугающий обилием кнопок и в тоже время любое действие выполняется на «раз - два - три».
На создание только версии под Windows 8 ушло 3 месяца (c учетом наработок в первой версии, с нуля было бы больше).

К слову. Вы замечали, что везде в Windows, такой элемент как PopUp - всегда один? Чтобы мы не открыли, всплывающая форма - всегда одна, если открыть другую - предыдущая закроется. У меня в интерфейсе была беда: датчик после активации закрывался через определенное время сам, но если активировать один, а потом другой сразу - они были открыты оба, выглядит не очень эстетично и понятно. Спасибо моему второму дизайнеру за этот фитбек. Он не принимал непосредственного участия в проекте, но некоторые вещи реализованы благодаря его наводкам.
Я неделю бился над решением этой проблемы.
И я ее решил…
Одной строчкой кода.
Мораль: иногда за самыми простыми решениями скрывается очень много работы.

Фитбеки от Microsoft

Прошлой весной Microsoft проводила акцию, где все разработчики могли получить бесплатные рекомендации по улучшению UI/UX своих продуктов. И мы успели на эту раздачу.
Если честно, то я боялся что разнесут все в пух и прах, это же был мой первый опыт с восьмеркой. Но, все прошло гладко, по словам заказчика, в Microsoft очень высоко оценили качество приложения. Мы получили несколько небольших рекомендаций по улучшению юзабилити (к слову очень грамотных) например это:


Очень верное замечание, берите на заметку. Если мы выделяем какой-то объект и далее возможны действия с ним - AppBar должен открыться сам! Показав пользователю эти самые возможные действия.
Вообще проблема гораздо шире, озвучу так - очевидные действия должны выполняться сами, не нужно ждать, когда это сделает пользователь.

Все поправки я внес менее чем за день. И на душе стало тепло и спокойно.

Итого

На данный момент система находиться в стадии разработки, у заказчика не так все хорошо, как хотелось бы. Поэтому и пишу пост спустя почти год, дата релиза неизвестна и сейчас.
Приложение можно потрогать из Windows Store тем у кого стоит Windows 8, но перед этим нужно поставить в настройках Турецкую локаль:
Панель управления->Время, язык и регион ->Регион -> Изменение расположения - > Турция (потом не забудьте вернуть, иначе маркет вам будет показываться Турецкий)
Но сейчас в Store лишь урезанная версия, демонстрируюшая основные возможности. Когда-нибудь система будет доделана, а так как мы переделывали старую - вероятность этого велика. Надеюсь, у заказчика дела пойдут в гору и мы продолжим работу над проектом. А работы там еще очень много: web версия, сайт, фирменный стиль (мы разработали лишь логотип и его идею, но надо развивать), версия под iOS, Android, WP8. да и версию под Windows 8 я бы сейчас немного переделал, мы ее закончили прошлым летом, с тех времен в WIndows много что поменялось, да и мои скилы в этой области подросли.

Ну и напоследок видео про версию на Windows 8 (cмотрите HD)

Есть еще видео от заказчика, но оно уж очень плохого качества.

PS. Об ошибках в статье пишите в личку.

Мы смогли научить нашу систему «умный дом» распознавать сказанное нами и синтезировать голосовые ответы при помощи Google.
Сегодня я хочу рассказать, как организовать доступ к нашей системе через веб-интерфейс.

Технологии

Как вы помните, ПО для управления нашим «умным домом» мы пишем на языке perl . Современная информационная система практически немыслима без БД. Мы тоже не останемся в стороне и для хранения наших данных будем использовать СУБД MySQL . Для реализации веб-сервера я решил воспользоваться не сторонним софтом, а модулем для perl - HTTP::Server::Simple , в частности - HTTP::Server::Simple::CGI . Для чего я это сделал? В большой части, ради интереса;) Но в теории, можно получить доступ к низкоуровневой обработке HTTP-запросов/ответов без нагромождения комплекса Apache/mod_perl. В целом, ничего не мешает перевести проект на рельсы Apache, если у вас будет желание и достаточно времени.

База данных

Первым делом установим СУБД MySQL и создадим базу с таблицами из db.sql. Вот листинг:

CREATE DATABASE ion; USE ion; # # Table structure for table "calendar" # DROP TABLE IF EXISTS calendar; CREATE TABLE `calendar` (`id` int(15) NOT NULL AUTO_INCREMENT, `date` datetime NOT NULL, `message` text, `nexttimeplay` datetime NOT NULL, `expired` datetime NOT NULL, `type` int(1) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1; # # Table structure for table "commandslog" # DROP TABLE IF EXISTS commandslog; CREATE TABLE `commandslog` (`id` int(15) NOT NULL AUTO_INCREMENT, `date` datetime NOT NULL, `cmd` varchar(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; # # Table structure for table "log" # DROP TABLE IF EXISTS log; CREATE TABLE `log` (`id` int(15) NOT NULL AUTO_INCREMENT, `date` datetime NOT NULL, `message` varchar(255) NOT NULL, `level` int(1) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

Выполним необходимые действия:

Nix@nix-boss:~$ sudo apt-get install mysql-server
nix@nix-boss:~$ mysql -uroot -ppassword < db.sql

Модифицируем код

Теперь нам необходимо создать папки lib , html и config (рядом с папкой data ). В папку lib мы положим модуль, отвечающий за реализацию веб-сервера и обработку наших HTTP-запросов.

Нам нужно немного подправить скрипт srv.pl . Добавим к блоку инциализации:

Our %cfg = readCfg("common.cfg"); our $dbh = dbConnect($cfg{"dbName"}, $cfg{"dbUser"}, $cfg{"dbPass"});
Добавим строки, отвечающие за запуск HTTP-сервера ниже блока инициализации:

## Запуск HTTP-сервера ################################ my $pid = lib::HTTP->new($cfg{"httpPort"})->background(); print "HTTP PID: $pid\n"; logSystem("Сервис HTTP - PID: $pid, порт: $cfg{"httpPort"}, хост: $cfg{"httpHost"}", 0); ################################
А теперь добавим недостающие функции в конец файла:

Sub readCfg { my $file = shift; my %cfg; open(CFG, "; foreach my $line (@cfg) { next if $line =~ /^\#/; if ($line =~ /(.*?) \= \"(.*?)\"\;/) { chomp $2; $cfg{$1} = $2; } } close(CFG); return %cfg; } ######################################## sub dbConnect { my ($db, $user, $pass) = @_; return $dbh = DBI->connect("DBI:mysql:$db", $user, $pass) || die "Could not connect to database: $DBI::errstr"; } ######################################## sub logSystem { my ($text, $level) = @_; my %cfg = readCfg("common.cfg"); dbConnect($cfg{"dbName"}, $cfg{"dbUser"}, $cfg{"dbPass"}); $dbh->do("INSERT INTO log (date, message, level) VALUES (NOW(), "$text", $level)"); }

Как можно понять по названиям функций, dbConnect() - отвечает за соединение с нашей СУБД, logSystem() - за логгирование, readCfg() - за загрузку конфигурации. Остановимся на ней подробнее. Конфигурация представляет собой простой текстовый файл в директории config. В нашем случае, он называется common.cfg . Выглядит примерно так:

## Настройки daemonMode = "undef"; logSystem = "1"; logUser = "1"; dbName = "ion"; dbUser = "root"; dbPass = "password"; camNumber = "4"; camMotionDetect = "1"; httpPort = "16100"; httpHost = "localhost"; telnetPort = "16000"; telnetHost = "localhost"; micThreads = "5";

Некоторые строки в нем будут использованы позже. Нас же пока интересуют только строки, начинающиеся с префикса db . Как мы видим - это настройки для соединения с нашей БД.

Теперь расскажу о том, как побороть многократное выполнение команды. Подредактируем функцию checkcmd() :

Sub checkcmd { my $text = shift; chomp $text; $text =~ s/ $//g; print "+OK - Got command \"$text\" (Length: ".length($text).")\n"; if($text =~ /система/) { ################################################# my $sth = $dbh->prepare("SELECT cmd FROM commandslog WHERE DATE_SUB(NOW(),INTERVAL 4 SECOND) <= date LIMIT 0, 1"); $sth->execute(); my $result = $sth->fetchrow_hashref(); if($result->{cmd} ne "") { return; } $dbh->do("INSERT INTO commandslog (date, cmd) VALUES (NOW(), "$text")"); ################################################# if($text =~ /провер/) { my $up = `uptime`; $up =~ /up (.*?),/; sayText("Время работы сервера - $1. Номер главного процесса - $parent."); } if($text =~ /врем/) { my $up = `uptime`; $up =~ /(.*?) up/; sayText("Сейчас $1"); } if($text =~ /законч/ || $text =~ /заверш/) { sayText("Завершаю работу. Всего доброго!"); system("killall motion"); system("rm ./data/*.flac && rm ./data/*.wav"); system("killall perl"); exit(0); } if($text =~ /погод/) { my ($addit, $mod); my %wh = lib::HTTP::checkWeather(); $wh{"condition"} = Encode::decode_utf8($wh{"condition"}, $Encode::FB_DEFAULT); $wh{"hum"} = Encode::decode_utf8($wh{"hum"}, $Encode::FB_DEFAULT); $wh{"wind"} = Encode::decode_utf8($wh{"wind"}, $Encode::FB_DEFAULT); if($wh{"temp"} < 0) { $mod = "ниже нуля"; } if($wh{"temp"} > 0) { $mod = "выше нуля"; } $wh{"wind"} =~ s/: В,/восточный/; $wh{"wind"} =~ s/: З,/западный/; $wh{"wind"} =~ s/: Ю,/южный/; $wh{"wind"} =~ s/: С,/северный/; $wh{"wind"} =~ s/: СВ,/северо-восточный/; $wh{"wind"} =~ s/: СЗ,/северо-западный/; $wh{"wind"} =~ s/: ЮВ,/юго-восточный/; $wh{"wind"} =~ s/: ЮЗ,/юго-западный/; sayText("Сейчас $wh{"condition"}, $wh{"temp"} градусов $mod. $wh{"hum"}. $wh{"wind"}"); if ($wh{"temp"} <= 18) { $addit = sayText("Одевайтесь теплее, на улице холодно!"); } if ($wh{"temp"} >= 28) { $addit = sayText("Переносной кондиционер не помешает!"); } } } #sayText("Ваша команда - $text"); return; }
Мы выбираем последнюю выполненную команду в интервале четырех секунд и если она совпадает с текущей - выходим из функции. Как вы можете заметить, я добавил некоторые команды, по сравнению с описанной функцией в прошлой статье. Наиболее интересная - это погода. Реализация получения данных для нее - чуть ниже.

Модуль HTTP.pm

Вернемся к реализации встроенного HTTP-сервера. Создадим файл HTTP.pm в директории lib . Запишем туда следующий код:

Package lib::HTTP; use HTTP::Server::Simple::CGI; use LWP::UserAgent; use URI::Escape; use base qw(HTTP::Server::Simple::CGI); use Template; ######################################### ######################################### our %dispatch = ("/" => \&goIndex, "/index" => \&goIndex, "/camers" => \&goCamers,); our $tt = Template->new(); ######################################### ######################################### sub handle_request { my $self = shift; my $cgi = shift; my $path = $cgi->path_info(); my $handler = $dispatch{$path}; if ($path =~ qr{^/(.*\.(?:png|gif|jpg|css|xml|swf))}) { my $url = $1; print "HTTP/1.0 200 OK\n"; print "Content-Type: text/css\r\n\n" if $url =~ /css/; print "Content-Type: image/jpeg\r\n\n" if $url =~ /jpg/; print "Content-Type: image/png\r\n\n" if $url =~ /png/; print "Content-Type: image/gif\r\n\n" if $url =~ /gif/; print "Content-Type: text/xml\r\n\n" if $url =~ /xml/; print "Content-Type: application/x-shockwave-flash\r\n\n" if $url =~ /swf/; open(DTA, "<$url") || die "ERROR: $! - $url"; binmode DTA if $url =~ /jpg|gif|png|swf/; my @dtast = ; foreach my $line (@dtast) { print $line; } close(DTA); return; } if (ref($handler) eq "CODE") { print "HTTP/1.0 200 OK\r\n"; $handler->($cgi); } else { print "HTTP/1.0 404 Not found\r\n"; print $cgi->header, $cgi->start_html("Not found"), $cgi->h1("Not found"), $cgi->h2($cgi->path_info()); $cgi->end_html; } } ## Обработка запроса / ######################################## sub goIndex { my $cgi = shift; # CGI.pm object return if !ref $cgi; my %w = checkWeather(); my $cmd; my $dbh = iON::dbConnect($iON::cfg{"dbName"}, $iON::cfg{"dbUser"}, $iON::cfg{"dbPass"}); my $sth = $dbh->prepare("SELECT cmd FROM commandslog WHERE id > 0 ORDER BY id DESC LIMIT 0, 1"); $sth->execute(); my $result = $sth->fetchrow_hashref(); if($result->{cmd} ne "") { $cmd = $result->{cmd}; } else { $cmd = "Нет комманд..."; } print "Content-Type: text/html; charset=UTF-8\n\n"; my $uptime = `uptime`; $uptime =~ /up (.*?),/; $uptime = $1; my $videosys = `ps aux | grep motion`; if ($videosys =~ /motion -c/) { $videosys = "работает"; } else { $videosys = "не работает"; } my $micsys = `ps aux | grep mic`; if ($micsys =~ /perl mic\.pl/) { $micsys = "работает"; } else { $micsys = "не работает"; } my $vars = { whIcon => $w{"icon"}, whCond => $w{"condition"}, whTemp => $w{"temp"}, whHum => $w{"hum"}, whWind => $w{"wind"}, cmd => $cmd, uptime => $uptime, video => $videosys, mic => $micsys, threads => $iON::cfg{"micThreads"}, }; my $output; $tt->process("html/index", $vars, $output) || print $tt->error(), "\n"; } ## Обработка запроса /camers ######################################## sub goCamers { my $cgi = shift; # CGI.pm object return if !ref $cgi; my %w = checkWeather(); my $cmd; my $dbh = iON::dbConnect($iON::cfg{"dbName"}, $iON::cfg{"dbUser"}, $iON::cfg{"dbPass"}); my $sth = $dbh->prepare("SELECT cmd FROM commandslog WHERE id > 0 ORDER BY id DESC LIMIT 0, 1"); $sth->execute(); my $result = $sth->fetchrow_hashref(); if($result->{cmd} ne "") { $cmd = $result->{cmd}; } else { $cmd = "Нет комманд..."; } if($cgi->param("text") ne "") { my $txt = $cgi->param("text"); require Encode; $txt = Encode::decode_utf8($txt, $Encode::FB_DEFAULT); iON::sayText($txt); } print "Content-Type: text/html; charset=UTF-8\n\n"; my $vars = { camera1 => "video-0/camera.jpg", camera2 => "video-1/camera.jpg", camera3 => "video-2/camera.jpg", camera4 => "video-3/camera.jpg", whIcon => $w{"icon"}, whCond => $w{"condition"}, whTemp => $w{"temp"}, whHum => $w{"hum"}, whWind => $w{"wind"}, cmd => $cmd, }; my $output; $tt->process("html/camers", $vars, $output) || print $tt->error(), "\n"; } ## Погода ######################################## sub checkWeather { my %wh; my $ua = LWP::UserAgent->new(agent => "Mozilla/5.0 (Windows NT 5.1; ru-RU) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.872.0 Safari/535.2"); my $content = $ua->get("http://www.google.com/ig/api?hl=ru&weather=".uri_escape("Санкт-Петербург")); $content->content =~ /(.*?)<\/current_conditions>/g; my $cond = $1; $cond =~ /

Разберем содержимое подробнее. В хэше %dispatch мы определяем соответствие URL-адреса и вызываемой функции. Все прочие URL, не описанные в этом хэше, будут выдавать страницу 404 .
Шаблонизатором у нас будет выступать мощная и гибкая библиотека Template Toolkit . Её мы инициализируем строкой:

Our $tt = Template->new();
Перегружая функцию handle_request() родительского класса, мы получаем управление обработкой запросов к HTTP-серверу. Для отдачи браузеру статического контента (png, gif, jpg, css, xml, swf) используется блок:

If ($path =~ qr{^/(.*\.(?:png|gif|jpg|css|xml|swf))}) { my $url = $1; print "HTTP/1.0 200 OK\n"; print "Content-Type: text/css\r\n\n" if $url =~ /css/; print "Content-Type: image/jpeg\r\n\n" if $url =~ /jpg/; print "Content-Type: image/png\r\n\n" if $url =~ /png/; print "Content-Type: image/gif\r\n\n" if $url =~ /gif/; print "Content-Type: text/xml\r\n\n" if $url =~ /xml/; print "Content-Type: application/x-shockwave-flash\r\n\n" if $url =~ /swf/; open(DTA, "<$url") || die "ERROR: $! - $url"; binmode DTA if $url =~ /jpg|gif|png|swf/; my @dtast = ; foreach my $line (@dtast) { print $line; } close(DTA); return; }
Так как MIME-типов у меня получилось немного, я записал их чуть по-индусски;)
Дальше начинаются функции, отвечающие за генерацию контента определенного URL. Пока их всего две - индекс и страница с камерами.
На индексе мы сможем увидеть, работают ли такие подсистемы, как видео- и аудио-захват. Отдельной строкой идет:

My %w = checkWeather();
Эта функция возвращает хэш с текущими данными о погоде в городе, которые будут отображаться на нашей странице. Такая мелкая приятная плюшка;)
Там же рядом мы будем выводить последнюю полученную и распознанную команду для «умного дома».

Следующая функция goCamers() выполняет те же функции, что и индекс, только вместо вывода информации по состоянию подсистем, показывает изображение с наших камер и имеется возможность написать какой-либо текст, который будет синтезирован и озвучен нашим «умным домом».

Все странички строятся на основе шаблонов, лежащих в папке html . Выкладывать листинг здесь будет не удобно, поэтому дам ссылку на архив -

Это система управления домом по сценариям. Она позволяет навешивать произвольную логику (сценарии) на различные события в доме (срабатывание датчиков, нажатия кнопок, события от внешних сервисов, например, получнеие email или сообщения в twitter). Система имеет модульную архитектуру, весь функционал находится в плагинах. Если нужно добавить новый тип события или новые команды «домашнего API», нужно просто добавить плагин для этого.

В феврале у нас был . Первая версия включала фреймворк для домашней автоматизации: систему плагинов и инфраструктуру для них (чтобы плагины могли описывать свой API и события, а также использовать API и подписываться на события друг друга). Сейчас близится релиз второй версии, основная фича которого - новый веб-интерфейс.

UI теперь - модульное одностраничное приложение . Плагины могут описывать свой UI в виде html/js/css файлов, расположенных в ресурсах DLL. Клиентская часть UI основана на backbone.js и marionette.js , модули загружаются через require.js . В целом получилось довольно удобно для авторов плагинов - даже не имея глубоких знаний java script, можно, смотря в примеры, описать полноценный UI, который будет автоматически подключен в интерфейс управления домом.


Интерфейс управления домом состоит из «разделов», каждый плагин может содержать несколько разделов (а может содержать только один или может вообще не иметь интерфейса). Разделы поделены на 2 группы: системные (различные настройки, например, раздел домашних сценариев) и пользовательские (разделы, с которыми пользователи работают в повседневной жизни, например, «прогноз погоды» и «будильники»).

Также есть специальная страничка - «рабочий стол» (он же «стартовая страничка»). Там находятся «элементы стартовой страницы» - небольшие панели, которые отображают полезную информацию, а при клике на них открывается какая-нибудь страница или выполняется какое-либо действие.

стартовая страничка

раздел с будильниками (в нужное время проиграет музыку или запускает выполнение сценария)

раздел с прогнозом погоды (загружается из интернета)

редактор сценариев (на скриншоте сценарий, который фотографирует посетителей, нажавших кнопку дверного звонка)

страничка подписки на события: первый выпадающий список - события в системе (они описаны в плагинах), второй список - сценарии

Интерфейс адаптируется под маленькие экраны мобильных устройств.

стартовая страничка на маленьком экране

страничка с погодой на маленьком экране

Сейчас, как я уже писал, система быстро приближается к релизу 2-й версии, исходный код лежит на github . Пока еще есть возможность что-то поменять. Очень хотелось бы получить конструктивную критику и предложения по улучшению (а если кто-то пришлет pull request, я буду просто счастлив).

Если кто-то захочет попробовать вживую, как все работает, напишите мне личное сообщение - соберу для вас свежий дистрибутив.

PS.
Кстати, я пробовал работать над этим проектом и это дало удивительные результаты. Сейчас идет 8-ая неделя работы в таком режиме (Longest streak 49 days). За это время проект продвинулся вперед больше, чем за предыдущие пол года. Я очень доволен результатом и планирую продолжать работать в таком режиме, сколько это будет возможно.

В основе качественного интерфейса «Умного дома» всегда лежит мощная программная платформа. На этой базе интегратор создает визуализацию для конкретного проекта. Первое – инструмент, второе - продукт, который с его помощью создается (так же, как программа Автокад и чертеж, текстовый редактор и текст).

Есть два подхода к выбору платформы: 1. использование «родного» ПО, которое предоставляет производитель комплектующих, и 2. внедрение программного продукта независимого разработчика.

Родное приложение

Как мы упоминали в статье про , существует множество протоколов домашней автоматизации и еще больше производителей оборудования. Такие компании как Crestron, AMX, Vantage, RTI, HDL, ABB, Gira, Jung, Schneider-Electric, Vimar предлагают решения для мобильных устройств в комплекте с сенсорными управляющими панелями или со специализированными серверами визуализации.

  • Лицензия на ПО отдельно не покупается, но сама сенсорная панель или сервер стоит достаточно дорого.
  • Графика и структура такого интерфейса создается разработчиками. Однако это накладывает определенные ограничения: адаптация под конкретный проект возможна только в жестко заданных рамках.
  • Редакторы достаточно просты в использовании, и программисту с ними удобно работать.
  • Доступны интересные фирменные плагины (часы и будильник, предустановленные сценарии).
  • Функционал предопределен и нет возможности решать специфические задачи.
  • Совместимо только с тем стандартом автоматизации, для которого предназначено оборудование.
  • Интеграция с прочим оборудованием возможна только, если это заложено производителем. Так, например, с популярными аудио-системами Sonos совместимы практически все приложения, а вот подключить к ним, например, не получится.

Использовать «родные» программные продукты производителей, на наш взгляд, целесообразно в нескольких случаях.

Во-первых , если у вас будет гомогенная система, к которой не планируется подключать оборудование, поддерживающее иные протоколы.
Во-вторых , если вы планируете установить сенсорные настенные панели.
В-третьих , если ваш проект рассчитан именно на домашнюю автоматизацию – управление комфортом коттеджа или квартиры.

Если же сенсорные панели покупать не планируется, второй вариант может быть предпочтительным.

Стороннее приложение

Существует несколько программных комплексов, предназначенных для управления «Умным домом» с мобильных устройств. На наш взгляд, наиболее интересными являются iRidium и Evika. Они предоставляют сходные возможности, мы чаще используем iRidium, поэтому расскажем о нем.

Комплекс iRidium позиционируется как операционная система для умного дома, чем фактически и является. Он используется для объектов частного, коммерческого, промышленного назначения.

  • Для использования Иридиума в проекте необходимо приобрести лицензию у разработчика. Существует несколько типов лицензий, которые различаются числом подключаемых мобильных устройств и списком совместимого оборудования.
  • Приложение совместимо со всеми основными протоколами автоматизации, может управлять одновременно несколькими физически не связанными подсистемами. Для пользователя все управление при этом происходит из одного интерфейса.
  • Графическая часть очень гибко настраивается. Можно использовать типовые или индивидуально разработанные шаблоны, реализовать любую структуру и любые пожелания заказчика.
  • Может быть установлено на любые устройства, дополнительное оборудование (сервер или процессор) не требуется.
  • Настройка и прорисовка интерфейса – достаточно трудоемкий процесс.

Мы предпочитаем второй вариант, если

  • в качестве настенных сенсорных панелей используется iPad в рамке ;
  • система составная и нужно в один интерфейс включить управление разным оборудованием;
  • хочется персонализированный и подходящий именно для вашего проекта дизайн;
  • необходимо интегрировать автоматизацию со сторонним ПО, к примеру,

Интерфейс – это то, что пользователю «умного дома» приходится видеть и осязать каждый день. Поэтому понятному и отлично продуманному интерфейсу отводится важное место в интеллектуальной системе. Он должен отражать основные задачи и не перегружаться излишними функциями и компонентами. Качественный интерфейс умного дома – это непременная составляющая системы, он является гарантом удобного и эффективного управления интеллектуальным домом, с которым легко и просто управляется пользователь.

Что такое интерфейс

Под этим определением понимается метод взаимных действий между пользователем и системой посредством конкретного устройства, и в данном рассматриваемом случае – это сенсорная панель .

Чтобы получать от взаимодействия с ним комфорт и удовольствие, необходимо разрешить главные вопросы интерфейса: как будет выглядеть дисплей? Какие должны быть на нем отображены кнопки? Легко ли будет поменять функции, которые уже есть? Как упростить поиск нужных параметров?

Что включает интерфейс

Если рассматривать его в более широком толковании, то он представляет собой базу, в которой собраны различные способы контакта пользователя с системой «умный дом». «Общение» с ней, достигается с использованием разных устройств.

Например:

  • сенсорной панелью;
  • пультом дистанционного управления;
  • кнопочными панелями выключателями и панели;
  • мобильным телефоном посредством звонков GSM и СМС-сообщений;
  • устройством управления с помощью Интернета (компьютер, планшет, смартфон);
  • голосовым управлением.

Каким он должен быть

Система «Умный дом» — это сложная структурная композиция. Однако внутренняя сложность не должна являться таковой при ее использовании, а быть как можно проще. Чем нужно руководствоваться при выборе интерфейса.

Вот главные принципы:

  • Простота и удобство . Управление сценариями и функциями не должно отнимать много времени, а делаться разовыми кликами. Интерфейс должен быть понятен и прост как для родственников в возрасте, так и для детей. И только необходимая информация должна поступать на экран, а иконки быть такими, чтобы их легко можно было узнавать. Понятный и логичный алгоритм управления.
  • Безопасность . Интерфейс должен предоставлять возможность блокировки некоторых функций во избежание запуска нежелательной функции посторонним людям или детям. Отдельные страницы должны защищаться паролем.
  • Гармоничный дизайн . Интеллектуальный дом должен быть красив во всем. И интерфейс не исключение, поскольку каждое устройство, будь то контроллер или сенсор, является неотъемлемой частью интерьера и должен быть гармонично вписан в дизайн. Не должны выделяться из него даже встроенные панели, а быть лицом интерьера. Благо существует множество цветовых оттенков, обложечных графических тем и иконок, чтобы создать единый стиль.

Всем этим требованиям вполне отвечает, например, веб-интерфейс умного дома блочно-колоночной организации. К примеру, первый блок или группа их задействуется на камерах наблюдения для отражения информации, второй – на системе отопления, третий – на устройствах энергетики, чтобы проводить индикацию состояния устройств или потребления энергии.

В заключение

Нормальное системное функционирование не может быть обеспечено без интерфейса. Принцип работы универсального средства управления основывается в первую очередь на возможности выхода в Интернет, то есть на той платформе, которая дает возможность контролировать комплексно системы автоматизации. Кроме этого интерфейс интеллектуальной системы умного дома служит гарантом информационного контакта и поддержки функциональности.

Система должна иметь совместимость с любым персональным компьютером или мобильными устройствами, имеющими разные платформы.

Также как и общие интерфейсы, в систему включены локальные средства функционального управления. В большинстве своем они представлены разного рода выключателями, сенсорными и клавишными панелями, имеющими узкий функционал.

Например, устройство, которое установлено в комнате на одной из стен, может управлять освещением и климатом. Нажатием клавиш вы определяете необходимые операции – включаете слабый свет, поднимаете температуру в помещении и т.д. Можно включить ряд функций сценарий.