Linux на борту: Что делать со старым компьютером?: Автоматизация дома с помощью X10

Питер превращает свой старый ноутбук в контроллер удаленных устройств

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

Питер Сибах, автор, Независимый

Питер Сибах (Peter Seebach) работает с компьютерами много лет и постепенно приспособился. Хотя он до сих пор не понимает, почему мышку надо чистить так часто.



02.09.2008

Как работает X10

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

Для отправки сигналов X10 вам понадобится нечто, включаемое в розетку и имеющее интерфейс для подключения к компьютеру. Такие устройства бывают двух видов - с USB или последовательным интерфейсом RS-232; у меня - вариант с последовательным интерфейсом. Стоят они около $30 и выпускаются различными производителями; мое устройство называется Smarthome 1132B (ссылку на описание см. в разделе Ресурсы). На аппаратном уровне эта штука представляет собой обычный приемопередатчик: она принимает сигналы X10 и передает в компьютер через последовательный порт. Обратный процесс происходит аналогично - сигналы принимаются с порта и передаются в электрическую сеть. Сигналы являются широковещательными - их получают все устройства. Чтобы, однако, работа не превратилась в цирк, каждый сигнал содержит коды, показывающие, какому именно устройству он предназначен.

В общем случае сигнал содержит код дома, код прибора и код функции. Код дома, как следует из названия, используется для деления всего множества устройств на большие группы; всего таких кодов 16 - от A до P. Стандартный X10-контроллер может иметь четыре двухпозиционных переключателя, соответствующих разрядам 1-4, и клавиши для ввода кода дома. Если количество устройств, используемых вами, не очень велико, вам скорее всего хватит одного кода дома. Коды приборов, находящиеся в диапазоне от 1 до 16, служат для обозначения конкретных устройств. Некоторые старые устройства могут не поддерживать коды приборов за пределами диапазона от 1 до 8 и/или коды домов за пределами диапазона от A до H.

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


Оборудование и подключение

Подключается оборудование на удивление легко. Устройство, которое я раздобыл, включается в обыкновенную розетку и по внешнему виду напоминает блок питания для мобильной электроники. Оно снабжено разъемом RJ-45 для приема и передачи сигналов. В комплект также входит кабель со стандартным 9-штырьковым разъемом для подключения к последовательному порту. "No flow control, 9600, 8N1". Все как обычно.

Работать с последовательным портом в Linux® довольно просто. По умолчанию к порту имеют доступ только члены группы uucp; я добавил свою учетную запись в эту группу, завершил текущий сеанс и начал новый.

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

Листинг 1. Открытие последовательного порта и задание параметров
   int fd;
   struct termios t;

   fd = open(dev, O_RDWR);
   if (fd < 0) {
      fprintf(stderr, "Error opening '%s': %s\n",
         dev, strerror(errno));
      return -1;
   }
   tcgetattr(fd, &t);
   cfsetspeed(&t, B9600);
   cfmakeraw(&t);
   t.c_cflag &= ~(CSIZE);
   t.c_cflag |= CS8;
   t.c_cflag &= ~(PARENB);
   tcsetattr(fd, TCSANOW, &t);

Переменная dev содержит путь к файлу устройства; по умолчанию это /dev/ttyS0. (Встроенный последовательный порт старого ноутбука Gateway, который я использую в примерах, распознается как COM1 или ttyS0. Я рассказывал об этом ноутбуке в первой статье цикла.) Значение переменной dev можно поменять в коде главной процедуры, например, на /dev/ttyUSB0, что соответствует последовательному порту USB порт-репликатора.

Настройки устройства можно поменять с помощью функций tcgetattr/tcsetattr из termios.h. Практически всегда удобнее сначала получить старые настройки и внести в них изменения, чем пытаться заполнить структуру termios с нуля. Основное правило заключается в том, чтобы установить требуемые флаги, снять ненужные и больше ничего не трогать.

Правда, иногда встречаются исключения из этого правила. В листинге 2 приведен фрагмент кода моей первой попытки:

Листинг 2. Неудачная попытка настройки размера символа
 t.c_cflag |= CS8;
t.c_cflag &= ~(PARENB | CS6 | CS7);

Этот, казалось бы правильный, код, устанавливает размер символа в 5 бит. Почему так получается? CS6 - это 0x10, CS7 - это 0x20, CS8 - это 0x30. Установка CS8 и снятие CS6 и CS7 дает 0x00, что соответствует CS5. Чтобы этот код заработал, нам надо снять все флаги и явным образом установить тот, что требуется.


Протокол

Откровенно говоря, в протоколе X10 есть что-то сюрреалистическое. Но еще более причудлив протокол описания сообщений X10, используемый моей штуковиной с RS-232. Сообщение занимает 5 байт - 0x63 ("отправка команды X10"), код дома, код прибора, код функции и число повторений. Все перечисленное берется из таблиц. К примеру, коды числа повторений (соответствующие требуемому числу повторов сигнала, что, например, используется в регуляторах яркости освещения), задаются с помощью букв от A до O, при этом A соответствует 1, B соответствует 2 и т. д. За исключением очень немногих параметров, таких как байт "отправить команду", все передаваемые значения находятся в диапазоне от 0x40 до 0x5F.

Интересным занятием оказывается поиск закономерностей в сообщениях протокола. Шестнадцатеричные коды X10 большей частью находятся в диапазоне 0x00-1F - складывается ощущение, что протокол RS232 просто прибавляет к ним 0x40, чтобы избежать совпадений с управляющими символами. В то же время коды X10 не содержат закономерностей, которые были бы видны неопытным глазом. Первые несколько кодов приборов, соответствующие номерам от 1 до 4, выглядят так: 0x0C, 0x1C, 0x04 и 0x14. (Коды приборов всегда содержат 0x10.) Коды приборов всегда четные, коды команд - всегда нечетные.

Как выясняется, протокол использует эту особенность. Для выполнения некоторых команд, например "выключить все приборы", код прибора указывать не требуется. При выполнении таких команд он просто опускается. Не устанавливается в ноль, как вы могли подумать - просто опускается. Команда при этом выглядит так: 0x63, код дома, код функции, 0x00, число повторений. Но поскольку все коды приборов являются четными, а коды функций - нечетными, неоднозначности не возникает.


Разработка программного интерфейса

Несмотря на то, что программный код для работы с X10 не особенно сложен, было бы неприятно переписывать его каждый раз заново. В UNIX® эта проблема решается с помощью утилиты, обеспечивающей отправку команд X10 из командной строки. Все остальные программы могут при необходимости использовать функции этой утилиты. После завершения разработки и отладки утилиты имеет смысл сменить ее группу на uucp и установить бит setgid для ограничения доступа к оборудованию X10.

При работе непосредственно с кодами порядок отправки команд X10 воспринимается однозначно, но анализ кодов - весьма утомительное занятие. Вместо того чтобы выяснять, какой параметр к чему относится, я написал утилиту таким образом, что она принимает сначала код команды, код дома и затем код прибора. Если команда не требует указания кода прибора, он не считывается. Команды, коды домов и приборов берутся из таблиц; пользователь задает эти параметры в символьной форме. Например, команда "x10 on a 1" включит прибор 1 в доме A. Посмотреть список доступных символьных кодов и числовых кодов, передаваемых адаптеру X10, можно, вызвав утилиту с ключом -h или командой "help".

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

Для разработки механизма поиска кодов я воспользовался структурой, ставящей строку в соответствие числу. Я мог бы добавить поле "флаги", но это пришло мне в голову только после того, как интерфейс был полностью написан, так что я просто пристроил флаги в биты, находящиеся за пределами положительного диапазона символьного типа. Оказывается, существует только один флаг, SUPPRESS_UNIT, использующийся с командами, не требующими указания прибора. Специальная команда none используется для отправки сообщений, не содержащих команд - некоторые модели программируемого оборудования X10 могут использовать эти сообщения для настройки параметров домов или устройств.

Расширение возможностей программы

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

Во-первых, было бы очень удобно иметь возможность присваивать устройствам символьные имена. В ходе тестирования я использовал в общей сложности три устройства (два из которых до сих пор валяются где-то дома) и пару раз забывал, какое из них какое. Другой полезной возможностью было бы создание конфигурационных файлов. Я выбрал традиционный и вполне типовой формат конфигурационного файла - в каждой его строке находятся три поля, разделенные пробелами. Эти поля содержат символьное имя устройства, код дома и код прибора. Строки, начинающиеся с символа '#', считаются комментариями. К примеру, файл, приведенный в листинге 3 содержит описание нескольких устройств:

Листинг 3. Соответствие имен устройств кодам домов и приборов
 # большая лампа у дивана в зале 
tvroom		 		  a		 		  1
# я подключился к игровой приставке моего младшего брата, чтобы подшутить над ним
n64		 		  a		 		  2

Коды домов и устройств ищутся так же, как при работе с командной строкой.

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


Подключение Web-интерфейса

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

Другой полезной функцией является настройка новых устройств X10. Контроллер лампы, которым я обзавелся для написания этой статьи, был настроен как устройство A1 и не имел никаких переключателей или ручек. Для настройки кода дома и кода прибора путем программирования, контроллер нужно включить и затем передать ему в течение 30 секунд три сообщения X10, содержащих требуемые коды. Эта функция идеально подходит для реализации с помощью простейшего Web-интерфейса, несмотря на то, что выполняется она не очень часто. Подойдет приведенный ниже скрипт:

Листинг 4. Настройка кода дома и кода устройства
#!/bin/sh
x10 none $*
x10 none $*
x10 none $*

Для программирования устройства нужно вызвать этот скрипт, указав код дома и код прибора или имя устройства из x10.conf.


Выполнение задач по расписанию с помощью cron

Использовать cron для выполнения по расписанию различных действий, например, для включения освещения, очень просто. Если вы хотите включать в доме свет по ночам, чтобы он выглядел обитаемым во время вашего отпуска, делать это в одно и то же время было бы не самым лучшим решением. Лучше внести в этот процесс элемент случайности. Следующий простой скрипт выполняет заданное действие в течение отрезка времени чуть меньше часа:

Листинг 5. Задержка на период менее часа
#!/bin/bash
sleep $((RANDOM / 10))
$*

Сохранив этот скрипт как /usr/local/bin/soonish, вы сможете затем создать следующее задание для cron:

Листинг 6. Включение лампы в течение вечера
0 18 * * *		 		  /usr/local/bin/soonish x10 on tvroom
0 21 * * *		 		  /usr/local/bin/soonish x10 off tvroom

Заключение и подсчет затрат

В этом месяце я превысил бюджет на закупку оборудования (см. мои пояснения, мотивы и ограничения расходов на написание этого цикла в статье "Linux on board: Breathe new life into an old machine"). Общая стоимость приемопередатчика X10, модуля лампы и документации составила $49.97. К сожалению, доставка обошлась в дополнительные $8. При этом документация оказалась бесполезной - в сети можно найти более качественные варианты. Более того, по непонятным для меня причинам в присланном мне комплекте было целых пять совершенно одинаковых книг, полных технических сведений по протоколу X10, но не содержавших указания на то, какие сигналы следует отправлять приемопередатчику. Так что пять долларов, потраченных на эту "документацию", вполне можно было сэкономить.

В перспективе было бы весьма полезно иметь несколько модулей для управления, но они стоят денег. И, похоже, будь я более внимательным, я мог бы уложиться в бюджет - у меня есть два модуля X10, которые я приобрел в 1997 году. Они бы работали не хуже нового.

Ресурсы

Научиться

Получить продукты и технологии

  • Smarthome торгует разнообразным оборудованием X10; кроме того, с их сайта можно загрузить руководства для этого оборудования. На странице устройства 1132b, которое купил Питер, есть ссылки на различную документацию и спецификации.(EN)
  • Начните ваш следующий проект для Linux с ознакомительными версиями ПО IBM, загрузить которые можно непосредственно с сайта developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


  • Bluemix

    Узнайте больше информации о платформе IBM Bluemix, создавайте приложения, используя готовые решения!

  • developerWorks Premium

    Эксклюзивные инструменты для построения вашего приложения. Узнать больше.

  • Библиотека документов

    Более трех тысяч статей, обзоров, руководств и других полезных материалов.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=334852
ArticleTitle=Linux на борту: Что делать со старым компьютером?: Автоматизация дома с помощью X10
publish-date=09022008