Адаптируем nooLite для работы с Apple HomeKit

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

Работу с объектом можно условно разделить на 3 этапа:


  1. Общение с заказчиком, получение информации об ожидаемых функциях системы и их приоритетах
  2. Установка и настройка
  3. Общение с заказчиком, получении отзыва о системе, недостающих функциях, функциях, оставшихся невостребованными.

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


f071e8424b3a40f7803272945e43b423.png

Я понимал, что этот процесс можно как-то упростить, однако всерьез этим не занимался. Но недавно на рынок вышли два интересных обновления, которые подтолкнули нас с @RagimovRV попробовать добавить моему и клиентским «Удобным домам» немного сообразительности.

Почти под каждой статьей на Habrahabr и Geektimes, в которой упоминается оборудование ноолайт, есть комментарий с вопросом: «Когда появится обратная связь?». Больше года назад на выставке в Санкт-Петербурге Игорь Чавлытко, директор компании Ноотехника, рассказывал, что они собираются начать работу над блоками с обратной связью и шифрованием, которые, возможно, будут работать на другой частоте. Все лето мы вели разговоры об ожидаемых блоках и обсуждали возможные функции.

Наконец, в середине октября к нам пришли первые тестовые устройства для выявления ошибок, тестирования новых возможностей и получения информации о недостающих функциях. Тестовый комплект состоит из двух силовых блоков и одного usb / uart приёмопередатчика. На блоках красуется маркировка SLF-200, из которой следует, что перед нами недиммируемый блок (sl), мощностью 200 Ватт (о чем говорит число) и новая буква F отныне указывает на использование нового протокола, о нём рассказано чуть ниже. Приёмопередатчик может быть подключен к компьютеру по USB порту или разобран и подключен по UART к Arduino, Raspberry Pi и подобным устройствам.

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


О протоколе:

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

Передача данных на адаптер:


ST MODE CTR RES CH CMD FMT DATA ID CRC SP
1 1 1 1 1 1 1 4 4 1 1
171 172

Ответ от адаптера (считывание данных с адаптера):


ST MODE CTR TOGL CH CMD FMT DATA ID CRC SP
1 1 1 1 1 1 1 4 4 1 1
173 174

Пожалуй, стоит расшифровать приведенные сокращения:

ST — Стартовый байт
MODE — Режим работы адаптера (приемник / передатчик, nooLite / nooLite F, сервисный режим)
CTR — Управление адаптером
RES — Зарезервирован, не используется
TOGL — Количество оставшихся ответов от адаптера
CH — Адрес канала, ячейки для привязки
CMD — Команда
FMT — Формат (Количество данных, передаваемых с командой)
DATA — 4 байта данных
ID — Идентификатор блока (Адрес устройства в системе nooLite-F)
CRC — Контрольная сумма
SP — Стоповый байт

Команды, которые были добавлены в новой версии блоков:


Код Команда Описание
128 Запрос состояния CMD_Read_State Запрос на получение состояния блока. В FMT содержится информация о поле с данными, которые запрашиваются. Ответ — CMD_SEND_STATE
129 Настройка устройства CMD_Write_State Настройка устройства. В FMT содержится адрес поля, которое будет настраиваться. D0…D3 переписываются в указанное поле. Ответ — CMD_SEND_STATE
130 Передача состояния CMD_Send_State Значение FMT = тип запрашиваемых данных или код ошибки; 0 — Общая информация

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

Сохраняются в долговременной памяти:


  • Запоминать состояние блока перед пропаданием электричества: да / нет
  • Режим работы блока: вкл+выкл / вкл+выкл+яркость
  • Запретить прием команд от системы nooLite 1.0: да / нет
  • Режим работы дополнительного входа: выключатель / кнопка / переключающий выключатель / не используется

Не сохраняются в долговременной памяти:


  • Запрет обработки команды временного включения
  • Запрет приема команд от системы nooLite 1.0 (т. е. можно запретить только до перезагрузки блока)


Круто! Но что делать с этой информацией?

На данный момент мы совместно с @AlekseevAV реализовали поддержку почти всех возможностей адаптера (кроме получения информации от пультов и датчиков), в небольшом адаптере на python, преобразующем UART API в HTTP API, совместимое с API шлюза nooLite. Код, документация и инструкция по установке доступны в репозитории на Bitbucket, который будет активно обновляться после публикации статьи.

Теперь с помощью HTTP GET запроса на 8080 порт компьютера, на котором запущен адаптер, можно выполнять любые действия, доступные в системе ноолайт.

Примеры использования:

http://192.168.2.18:8080/api.htm?ch=1&cmd=2&mode=0 # включение силового блока nooLite 1.0, привязанного на 1й канал
http://192.168.2.18:8080/api.htm?ch=8&cmd=0&mode=0 # выключение силового блока nooLite 1.0, привязанного на 8й канал
http://192.168.2.18:8080/api.htm?ch=1&cmd=2&mode=2 # включение силового блока nooLite 2.0 (F), привязанного на 1й канал
http://192.168.2.18:8080/api.htm?ch=0&cmd=8&mode=2 # запись сценария в силовой блок nooLite 2.0 (F), привязанный на 0й канал

Более подробно ознакомиться с API адаптера можно в официальном wiki.

Приятный бонус: адаптер MTRF-32, как видно из названия, поддерживает 32 канала, он совместим со старыми и новыми блоками, но адресация у старых и новых блоков разная. Таким образом, можно привязать 32 старых и 32 новых блока одновременно. Или 32 новых блока в обычном режиме и 32 в режиме обратной совместимости.

Второе приятное событие — появление иконки приложения «Дом» на всех мобильных устройствах Apple, обновленных до последней (10) версии операционной системы. Платформа HomeKit была представлена 2 июня на конференции WWDC'2014, но что она из себя представляет понимания не было, однако теперь просто неправильно было бы не знать, что кроется за этим значком.

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

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

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


  • Освещение
  • Розетки
  • Шторы

Часть блоков — SU (диммируемые зоны освещения), остальные — SLF.

Цель: начать управлять этим оборудованием через приложение «Дом» и голосом — через Siri. В качестве контроллера использовать Raspberry PI 3 c USB / UART приемопередатчиком nooLite.

В первую очередь необходимо установить HomeBridge на Raspberry Pi (полная и понятная инструкция находится в wiki официального репозитория, то есть здесь).

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

Мы решили, что лучшим вариантом взаимодействия между плагином для Homebridge и устройствами ноолайт будет выполнение HTTP запросов на localhost или ip Ethernet-шлюза согласно API шлюза или почти идентичного API программного адаптера на Python, о котором я рассказал в первой части статьи.

Для управления перечисленными в разделе «идея» устройствами мы написали три плагина, о каждом из которых расскажу по порядку:

Рулонная штора Somfy с электроприводом, подключенная через SR блок ноолайт, управляется с помощью сценарных кнопок, доступны команды вверх / вниз / стоп. Плагин для жалюзи, который был в npm, позволяет передать шторе команду двигаться вверх или вниз, но не поддерживает остановку в середине пути. Мы переделали этот плагин таким образом, чтобы команда «открой жалюзи на N%» работала корректно. При этом после команды полного открытия или закрытия жалюзи калибруется, и, если ранее её состояние было изменено не через HomeBridge, следующая команда открытия шторы на заданный уровень будет выполнена корректно. Ссылка на npm пакет. При правильно настроенном HomeBridge установка выполняется одной командой.

sudo npm install -g homebridge-noolite-http-blinds

Чтобы аксессуар заработал, нужно описать его в файле config.json, расположенном в папке ~/.homebridge/config.json. Пример описания шторы, которая привязана к моему адаптеру. Для управления используются 3 канала, каждый из которых отвечает за перевод шторы в определенное состояние:


  1. Движение вниз — 10 канал
  2. Стоп — 11 канал
  3. Движение вверх — 12 канал

Кроме того, необходимо задать параметр «motion time» — время движения шторы в миллисекундах, необходимое для перехода из полностью открытого в полностью закрытое состояние или наоборот.

   {
     "accessory": "NooLite-HTTP-Blinds",
     "name": "Штора",
     "up_url": "http://192.168.2.18:8080/api.htm?ch=12&cmd=7&mode=0",
     "down_url": "http://192.168.2.18:8080/api.htm?ch=10&cmd=7&mode=0",
     "stop_url": "http://192.168.2.18:8080/api.htm?ch=11&cmd=7&mode=0",
     "http_method": "GET",
     "motion_time": "31000"
    }

Розетка, отключающая аудиосистему мощностью 100 ватт, дабы та не шумела ночью. Розетка может находиться только в двух состояниях: включено или выключено, и кроме этого состояния никакую дополнительную информацию мы вывести в HomeKit не можем. После завершения плагина для штор нам очень легко дался этот плагин, и теперь вы тоже можете его установить. Ссылка на npm пакет.

sudo npm install -g homebridge-noolite-http-outlet

Пример описания розетки, привязанной к 3-ему каналу передатчика, при использовании нового SLF блока.

   {
      "accessory": "NooLite-HTTP-Outlet",
        "name": "Розетка",
        "on_url": "http://192.168.2.18:8080/api.htm?ch=3&cmd=2",
        "off_url": "http://192.168.2.18:8080/api.htm?ch=3&cmd=2",
        "status_url": "http://192.168.2.18:8080/api.htm?ch=3&cmd=128",
        "http_method": "GET"
    }

Управление светом — самый большой, сложный и интересный плагин. Он поддерживает включение / выключение / установку яркости для обычных светильников и настройку цвета для светодиодных лент, подключенных через SD блок. Ссылка на npm пакет.

sudo npm install -g homebridge-noolite-http-rgb

Пример описания светильника, привязанного к 3-ему каналу передатчика, при использовании старого SD блока.

   {
    "accessory": "NooLite-HTTP-RGB",
    "name": "RGB LED strip",

    "switch": {
            "powerOn": "http://192.168.2.18:8080/api.htm?ch=3&cmd=2&mode=0",
            "powerOff": "http://192.168.2.18:8080/api.htm?ch=3&cmd=0&mode=0"
        },

        "brightness": {
            "url": "http://192.168.2.18:8080/api.htm?ch=3&cmd=6&br=%s&mode=0"
        },

        "color": {
            "url": "http://192.168.2.18:8080/api.htm?ch=3&cmd=6&fmt=3&d0=%s1&d1=%s2&d2=%s3&mode=0"
        }
    }

Важное замечание: для управления диммируемыми лампами нужно задавать параметр «brightness», а для управления лентами — «color», оба параметра сразу указывать не нужно, т. к. при задании параметра «color», «brightness» игнорируется. На данный момент получение состояния блока не реализовано, эта возможность будет добавлена в следующих версиях.

Вишенка на торте — поддержка камер
Если посмотреть список возможных команд Siri для приложения «Дом», можно заметить очень интересную команду «покажи камеру в гостиной», что говорит о том, что HomeKit не просто поддерживает камеры для вывода на одном из экранов комнат, но позволяет еще и быстро открыть её с заблокированного экрана телефона. Мы разобрались, как добавить камеру с помощью HomeBridge.

В списке плагинов есть нечто под названием «camera-ffmpeg». Судя по инструкции, разработчик этого плагина использовал его только на маке, и работоспособность на других платформах, в нашем случае raspberry, не гарантируется. Мы решили попробовать и установили этот плагин, а также необходимый ему «ffmpeg». Для первоначального теста нашли RTSP поток с мультфильмами в интернете и добавили его в конфигурационный файл. Запустили HomeBridge, добавили через приложение виртуальную камеру, и она заработала, мультфильм успешно проигрывался на одном из экранов приложения «Дом», единственным нюансом было отключение примерно каждые 30 секунд.

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

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

Чтобы у вас заработала аналогичная конфигурация, можно не повторять проведенные действия с самого начала. Мы выложили готовый для сборки пакет FFMPEG, а также исправленный ffmpeg.js на яндекс диск. Ниже предлагаю краткую инструкцию по его установке:


  1. Скачиваем содержимое папки по ссылке выше в домашнюю директорию
  2. Переходим в папку с ffmpeg_omx.tgz
  3. Разархивируем ffmpeg_omx.tgz: tar -xvf ffmpeg_omx.tgz
  4. Заходим в папку ffmpeg и делаем make install (занимает 80+ мин)

Также необходимо установить плагин camera-ffmpeg, для этого выполняем следующую команду:

sudo npm install -g homebridge-camera-ffmpeg

Выяснилось, что камера отключается примерно после 30 секунд просмотра из-за того, что ffmpeg пытается вывести данные в консоль, а плагин никак не обрабатывает этот вывод. Чтобы предотвратить отключение камеры, изменяем плагин так, чтобы вывод ffmpeg попадал в »/dev/null». Это исправление добавлено в файл, который мы скачали первым шагом, поэтому просто заменяем файл «ffmpeg.js» в папке плагина и устанавливаем пакет, позволяющий плагинам писать в «dev/null».


  1. cp /home/alarm/ffmpeg.js /usr/lib/node_modules/homebridge-camera-ffmpeg/
  2. npm install -g dev-null

И задаем параметры для камеры в файле config.json

{
  "platform": "Camera-ffmpeg",
  "cameras": [
    {
      "name": "Camera Name",
      "videoConfig": {
        "source": "-re -i rtsp://myfancy_rtsp_stream",
        "maxStreams": 2,
        "maxWidth": 1280,
        "maxHeight": 720,
        "maxFPS": 30
      }
    }
  ]
}

Где «rtsp://myfancy_rtsp_stream» путь к rtsp потоку вашей камеры.

Теперь можно перенести камеру в правильную комнату, и она будет показывать картинку, обновляющуюся раз в секунду. При нажатии на это изображение откроется живое вещание, а Siri будет понимать, что делать, если сказать ей «покажи камеру в <название комнаты>».


Настройка на iOS

Для подключения HomeBridge к телефону необходимо зайти в приложение «Дом», нажать кнопку «Добавить аксессуар», в списке предложенных аксессуаров появится мост с заданным в настройках названием. Нажимаем на него и последовательно добавляем все предложенные аксессуары, при этом можно сразу расположить их в комнатах, к которым они принадлежат. Пример «config.json» файла для подключения светильников, жалюзи и розеток можно скачать по ссылке.

Спасибо за внимание! Надеюсь, статья оказалась интересной и полезной для вас.

© Geektimes