Я хочу представить вашему вниманию цикл статей по управляющим модулям Laurent (Лоран) компании KernelChip. В этом цикле я расскажу вам о том, как интегрировать эти модули в ваш Умный дом, как научиться управлять ими из популярной системы домашней автоматизации MajorDoMo, из скетчей Ардуино, из системы Arduino Mega Server и даже как применить эти модули для совершенно неожиданной цели — для обучения ваших детей программированию на языке Processing.

image

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


Почему Laurent?


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

И вы на основе этого кода сможете разрабатывать свои программные решения, это будет совсем несложно, ведь большую часть работы я уже проделал. Кроме того, код будет подробно объяснён, что безусловно способствует вашему пониманию того, как это работает, обучению программированию и построению систем Умного дома.

Сами модули


Когда я выбирал для себя какое-то готовое решение по управлению электрическими нагрузками через сеть, Лоран подкупил меня законченностью и простотой решения. Для того, чтобы начать управлять по сети включением и выключением приборов и освещения не нужно было практически ничего. Не нужно было изучать язык программирования, не нужно было ничего паять, достаточно было подключить модуль к локальной сети, подключить к клеммам реле нагрузку (и не забыть подать напряжение питания на сам модуль) и всё. После этого можно было посылать команды прямо с компьютера (из терминальной программы). Модуль сразу же стал послушно включать и выключать свет по моим командам. На тот момент мне большего не нужно было.

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

Дизайн и качество сборки


Достаточно просто посмотреть на модуль, чтобы стало понятно, что его разрабатывали не просто так, «лишь бы было», а старались сделать действительно достойную вещь. К качеству сборки у меня тоже нет никаких претензий, всё сделано аккуратно и так, как и должно быть: никаких криво стоящих деталей, подтёков припоя или чего-либо подобного, всё чётко и аккуратно. По большому счёту, качество сборки не отличается от «фирменных» компьютерных комплектующих и «заводских» Ардуино.

Единственное, что я сделал бы, если сам выпускал эти модули, это установил вместо одноцветных клемм для подключения проводов разноцветные, хотя бы выделил клеммы подключения питания, но это так, мелкие придирки (всё, естественно, аккуратно подписано).

О чём первая статья из цикла


Вся информация разбита на три логически законченные статьи. В первой статье речь пойдёт об интеграции модулей Лоран с популярной открытой платформой домашней автоматизации MajorDoMo. Будут даны конкретные примеры и код на языке PHP.

Во второй статье — об интеграции с экосистемой Arduino. Вы сможете управлять модулями из своих отдельных скетчей или интегрировать Laurent с Arduino Mega Server (который тоже основан на коде Ардуино) и управлять Лоранами из удобного интерфейса или автоматически, по программе. Так же будут даны готовые решения и протестированный код.

А в третьей — об управлении модулями Laurent из скетчей на Processing. То есть прямо с рабочего стола вашего домашнего компьютера. В этой же статье будет рассказано, как поднять интерес детей к изучению программирования и какую роль в этом деле могут сыграть эти модули.

Цикл посвящён интеграции модулей Laurent с системами домашней автоматизации и не рассматривает архитектуру и работу самих модулей. Об этом рассказывалось в других статьях, с которыми вы можете ознакомиться 1, 2, 3 и будет ещё рассказано позже. Здесь мы сосредоточимся только на интеграции.

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

Как работает управление модулями


Весь обмен информацией с модулями осуществляется по сети и для начала работы с ними нужно установить TCP/IP соединение на 2424 порту. Как только соединение установлено, можно посылать текстовые команды (т. н. КЕ команды) которые и управляют модулем. На сайте компании KernelChip есть подробная документация и, в том числе, доступное описание КЕ команд.

Компания KernelChip позаботилась о пользователях и снабдила свои модули удобным веб-интерфейсом, но это «ручное управление», а удобство, ценность и полезность решения возрастёт на порядок, если мы научимся управлять модулем из своего Умного дома.

image

Веб-интерфейс по умолчанию защищён паролём и чтобы увидеть содержимое веб-странички нужно ввести логин «admin» и пароль «Laurent».

MajorDoMo


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

Возможности MajorDoMo поистине безграничны и управление модулями Laurent это только один из талантов этой системы.

Технические подробности


MajorDoMo в своём составе имеет файл laurent.class.php, который находится в директории

\htdocs\lib

Полный код laurent.class.php
<?

function laurent_command($host, $command, $password='Laurent') {

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo «socket_create() failed: reason: ». socket_strerror(socket_last_error()). "\n";
return 0;
}

$result = socket_connect($socket, $host, 2424);
if ($result === false) {
echo «socket_connect( $socket, $host, 2424) failed.\nReason: ($result) ». socket_strerror(socket_last_error($socket)). "\n";
return 0;
}

$in='$KE'."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "\n"))) {
break;
}
}

$in='$KE,PSW,SET,'.$password."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "\n"))) {
break;
}
}

$in=$command."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "\n"))) {
break;
}
}

socket_close($socket);
return trim($res);

}

function laurent_getStat($host, $password='Laurent') {

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo «socket_create() failed: reason: ». socket_strerror(socket_last_error()). "\n";
return 0;
}

$result = socket_connect($socket, $host, 2424);
if ($result === false) {
echo «socket_connect( $socket, $host, 2424) failed.\nReason: ($result) ». socket_strerror(socket_last_error($socket)). "\n";
return 0;
}

$in='$KE'."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "\n"))) {
break;
}
}

$in='$KE,PSW,SET,'.$password."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "\n"))) {
break;
}
}

$command='$KE,DAT,ON';
$in=$command."\r\n";
socket_write($socket, $in, strlen($in));

$res='';
$started=0;
while ($out = socket_read($socket, 2048, PHP_NORMAL_READ)) {
$res.=$out;
if (is_integer(strpos($out, "#TIME,"))) {
if (!$started) {
$started=1;
} else {
break;
}
}
}

$command='$KE,DAT,OFF';
$in=$command."\r\n";
socket_write($socket, $in, strlen($in));
sleep(1);
socket_write($socket, $in, strlen($in));
socket_write($socket, $in, strlen($in));

socket_close($socket);
return trim($res);

}

?>


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

Основная функция, которая используется для управления модулем, это

laurent_command('<адрес устройства>', '<команда>', '<пароль к устройству>');


например,

$result = laurent_command('192.168.2.19', '$KE,INF', 'Laurent');


, где '192.168.2.19' это IP адрес модуля, '$KE,INF' — собственно команда, 'Laurent' это пароль (по умолчанию).

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

С командой должно быть всё понятно, вы можете брать любые команды из справочника и управлять модулем как хотите. IP адрес тоже не должен вызывать никаких вопросов. Просто указываете тот IP адрес, который реально имеет ваш Laurent модуль.

С теорией на этом можно закончить и сейчас я на практическом примере покажу вам как сделать управление светом (или электроприбором) прямо из меню MajorDoMo.

Практический пример


В качестве практического примера давайте рассмотрим создание двух кнопок «Включить» и «Выключить» в главном меню системы MajorDoMo. Этими кнопками вы можете включать и отключать свет или любой электроприбор (здесь нужно только помнить, что реле установленные на модуле не способны напрямую управлять мощной нагрузкой наподобие электроплиты или водонагревателя).

Итак, создаём кнопку «Включить», для этого идём в админку MajorDoMo и вводим логин и пароль (по умолчанию — admin/admin) и нажимаем на «ОБЪЕКТЫ / Меню управления» и далее на большую зелёную кнопку «Добавить новый раздел».

image

Далее находим выпадающий список «Тип» и выбираем из всего разнообразия представленных типов «Кнопка» и нажимаем «Сохранить».

image

Далее выбираем «Родительский пункт меню» это то место куда «прицепится» наша кнопка. У меня это Laurent, а у вас это может быть любой удобный пункт меню. По умолчанию там стоит «ROOT» это значит кнопка будет видна сразу, без нажатия на какой-либо пункт меню.

В поле ввода «Название» пишите то, что хотите, чтобы было написано на кнопке. И последнее, в поле «Код» пишите уже знакомый нам код функции laurent_command:

laurent_command('192.168.2.19', '$KE,REL,2,1', 'Laurent');


Здесь то же самое, что и в теоретическом примере, только отсутствует переменная $result (она нам не нужна) и команда заменена на '$KE,REL,2,1', что означает включить реле №2.

То же самое проделываем для кнопки «Выключить», только не забываем изменить название кнопки и вместо '$KE,REL,2,1' пишем '$KE,REL,2,0', что означает выключить реле №2:

laurent_command('192.168.2.19', '$KE,REL,2,0', 'Laurent');


На этом — всё. Перегружаем страничку с интерфейсом MajorDoMo, появляются две новые кнопки, которые прекрасно и практически без задержки включают и выключают свет (или электроприбор) прямо из интерфейса MajorDoMo. Чего мы и хотели достичь.

Автоматическое управление


Теперь давайте попробуем управлять модулем автоматически, без участия человека. Сейчас вы убедитесь, что это даже ещё проще, чем управление модулем при помощи кнопок.

image

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

image

И всё, что нам нужно сделать это добавить наш код в этот метод. Для примера рассмотрим такую ситуацию. Ваш модуль Laurent управляет ночным освещением во дворе вашего дома. И вы, например, хотите, чтобы свет включался в 21.00, а утром выключался в 7.30. Нет ничего проще, вот код который вы должны добавить в метод onNewMinute:

if (timeIs('21:00')) {
  laurent_command('192.168.2.19', '$KE,REL,2,1', 'Laurent');
}

if (timeIs('7:30')) {
  laurent_command('192.168.2.19', '$KE,REL,2,0', 'Laurent');
}


И всё! Согласитесь, это совсем несложно. Это только пример, логика работы может быть абсолютно любой и очень изощрённой. И таланты модулей Laurent не заканчиваются на включении и выключении нагрузок, их функционал значительно шире, но это не тема данной статьи, здесь мы рассматриваем только вопросы интеграции на простых примерах.

Получение и вывод данных модуля


И последний пример будет о том, как получить и вывести на веб-страничку MajorDoMo информацию, получаемую от модуля Laurent.

MajorDoMo это объектно-ориентированная система и вся работа происходит в ней через создание объектов и использование их данных (переменных) и методов (программного кода). Немного сложно? На самом деле ничего страшного и сейчас вы в этом сами убедитесь.

image

Итак, для примера используем уже существующий объект «ThisComputer» и добавим ему новое свойство «test». Для этого нажимаем на уже знакомый нам пункт меню «Объекты» в админке MajorDoMo, находим объект «ThisComputer» и нажимаем на пункт «Свойства», прокручиваем страничку до самого низа и находим поля ввода «Добавить новое свойство», вводим «test» и нажимаем «Обновить» (значение оставляем пустым).

image

На этом подготовительные операции можно считать законченными, мы добавили новое свойство «test» объекту «ThisComputer», которое и будем использовать в своих экспериментах.

Теперь наша задача состоит в том, чтобы запросить нужную информацию у модуля Laurent и занести её в свойство (переменную) «test» объекта «ThisComputer». Как же это сделать? Очень просто.

Добавляем такой код в уже знакомый нам метод onNewMinute:

$result = laurent_command('192.168.2.19', '$KE,INF', 'Laurent');
setGlobal('ThisComputer.test', $result); 


И каждую минуту MajorDoMo будет запрашивать у модуля необходимую информацию и обновлять переменную «test», которую мы можем использовать так, как нам будет нужно. Например, выводить на веб-страничку. Для этого в любом нужном нам месте странички помещаем такой код:

%ThisComputer.test%


Это т. н. макрос, который при загрузке странички вместо себя подставляет значение переменной, хранящийся в свойстве «test» объекта «ThisComputer». И в результате вы видите на веб-странице информацию переданную модулем Laurent в ответ на ваш запрос.

Как добавить макрос на страничку? Идём в меню админки и выбираем пункт «Домашние страницы» и выбираем любую нужную страничку или создаём новую при помощи большой зелёной кнопки «Новая страница». И добавляем макрос в любое нужное место на странице.

Промежуточный итог


Ну вот и всё. Вооружившись информацией из этой статьи, вы можете почувствовать себя настоящим властелином Laurent-ов и интегрировать эти модули в вашу систему Умного дома. А в следующей статье из цикла вы узнаете, как управлять модулями из ваших скетчей на Ардуино и из системы Arduino Mega Server.

Комментарии (4)


  1. beho1der
    24.09.2015 17:04

    Очень интересно, жду продолжения!


    1. smart_alex
      24.09.2015 17:18

      Чуть попозже будет полный комплект: как управлять и как получать данные с этих модулей на PHP (уже есть), Ардуино и Processing, из MajorDoMo, скетчей Ардуино, Arduino Mega Server и прямо со своего рабочего стола.


      1. beho1der
        24.09.2015 17:27

        А такой вопрос, куда прячете датчики температуры\влажности\освещенности чтобы особо не выделялись они? У меня есть только вариант при ремонте делать рядом с розеткой\выключателем вторую коробку с заглушкой и делать маленькие отверстия и размешать там датчики.


        1. smart_alex
          24.09.2015 17:39

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

          К сожалению, ниша дизайнерских корпусов для датчиков пуста и негде взять красивый корпус для встраивания своего датчика.