Что это
Как устроен умный дом?
С одной стороны — устройства: лампы, розетки, датчики. С другой стороны — экосистема: Алиса, Apple Home, Google Home. Приложение, голосовой помощник, сценарии — пульт от всего дома. Каждая экосистема общается с устройствами по собственному протоколу.
Пользователь выбирает не отдельные устройства, а связку целиком. Может оказаться, что нужное устройство не поддерживает его экосистему: подходящая лампа работает с Apple Home, а датчик протечки — только с Алисой. Чем больше устройств, тем выше вероятность, что связки «экосистема + устройства», закрывающей все потребности, не существует. Если нужного устройства не делает никто, пользователь собирает его сам — но ни одна экосистема такое устройство не поддерживает.
Хаб между устройствами и экосистемами
ThinkingHome.DeviceModel — это виртуальный хаб: программа, которая описывает подключённые устройства единообразно и отдаёт это описание тем, кто ими управляет.
Хаб знает про каждое устройство три вещи:
- к какому типу приборов оно относится;
- чем в нём можно управлять;
- какие показания оно отдаёт.
Связь с конкретным прибором — по MQTT, по Zigbee или по собственному протоколу производителя — берёт на себя драйвер: небольшая программа-посредник между хабом и устройством. Разница между протоколами остаётся внутри драйвера, а в хабе все устройства описаны одинаково.
Для экосистемы хаб выглядит как одно устройство, внутри которого находятся остальные. Так же она видит фирменные хабы производителей: например, мост Philips Hue, за которым скрыты лампы Zigbee. Разница в том, что за фирменным хабом стоит техника одного производителя, а за виртуальным — любая, для которой есть драйвер.
У хаба два вида потребителей, и они устроены по-разному.
Первый — экосистема. Она работает из облака, обращается к хабу по собственному протоколу и даёт человеку интерфейс: приложение, голосовой помощник, сценарии.
Второй — код, который выполняется рядом с хабом: скрипты автоматизации, сервисы, интеграции. Ему не нужен ни облачный протокол, ни человеческий интерфейс — нужен прямой доступ к устройствам из программы, и для этого у хаба есть API.
Разделение существенное. Протокол экосистемы описывает не все возможности устройств, а связь с облаком зависит от интернета. Локальный код таких ограничений не имеет: он видит модель хаба целиком и продолжает работать, когда связь с облаком пропала.
Из чего состоит хаб
Хаб устроен из четырёх частей: ядра, драйверов, адаптеров и API.
Ядро хранит описания подключённых устройств, принимает запросы, передаёт команды нужному устройству и рассылает уведомления об изменениях. Ядро не знает ни про конкретные приборы, ни про конкретные экосистемы — оно работает только с описаниями в единой модели.
Драйверы связывают ядро с устройствами. Драйвер переводит команду из модели в протокол прибора, а показания прибора — в значения модели.
Адаптеры связывают ядро с экосистемами. Адаптер отдаёт экосистеме описания устройств в её формате, принимает от неё команды и переводит их в модель.
API открывает доступ к устройствам из кода. Он работает с моделью напрямую, без перевода в чужой формат.
Из такого разделения следует главное свойство хаба: драйвер не знает, какие экосистемы подключены, а адаптер не знает, по какому протоколу работает устройство. Новое устройство подключается без правок в адаптерах, новая экосистема — без правок в драйверах.
Где что выполняется
Хаб работает на домашнем сервере — мини-компьютере, сетевом хранилище или любой машине, включённой постоянно. Драйверы выполняются в том же процессе, что и хаб, и они же задают требования к размещению сервера: одному нужен доступ к брокеру MQTT, другому — USB-адаптер для радиосвязи с приборами. Сервер ставят там, где такой доступ есть. Локальные скрипты выполняются рядом, на той же машине.
Экосистема работает из облака и не может обратиться к домашней сети напрямую. Между ними стоит прокси — программа на сервере с публичным адресом. Домашний сервер сам подключается к прокси и держит соединение, а прокси передаёт по нему запросы экосистемы и возвращает ответы. Входящие подключения к дому не нужны, поэтому внешний IP, проброс портов и динамический DNS настраивать не требуется.
Прокси не хранит состояния устройств и не принимает решений — он только передаёт запросы. Развернуть его можно на любом сервере с публичным адресом, своём или арендованном.
Домашний сервер нужен всегда. Прокси нужен для экосистем, которые работают из облака; скриптам, выполняющимся рядом с хабом, он не требуется.