Уже год я разрабатываю домашнюю автоматизацию. За основу взял MQTT-протокол, как популярный стандарт и Wi-Fi в качестве транспорта, чтобы не сильно углубляться в эти ваши ZigBee, Lora и прочее, а разрулить всё привычными средствами. Хотелось локального управления устройствами и отвязка от облаков. Не со всеми устройствами это удалось - с кондиционерами и водонагревателем Electrolux я прогадал. В самом начале садился за разработку ибо после переезда и других дел хватало. Натыкал в пяти вендорских приложениях расписания и грыз кактус от того, какое оно не гибкое. Об MQTT не знал ничего и понятным языком никто не сказал “бери это, делай это, в целом оно выглядит как-то так”. Вот этот пробел я и попробую восполнить. Протокол очень простой и клёвый, этим он мне и нравится. Рекомендую.

Брокер

Есть брокер, есть клиенты. В этом плане система управляющая умным домом ничем не отличается от устройств, она - такой же клиент, который подключается к брокеру. Брокер - это что-то среднее между RabbitMQ и Redis. Я использую брокер mosquitto - вроде +/- устоявшийся стандарт. Не ресурсоёмкий, простой в настройке. Есть ещё один на erlang, с ним было сложно.

Топики

У брокера есть топики. Эдакие ключи, в терминологии Redis, которые key-value. Структура топиков обычно иерархична, но стандарта на неё нет. Как правило это что-то типа /вендор/имя_устройства/параметр. На топики можно подписываться (прям как в rabbitmq), для этого их нужно заранее знать. После подписки на топик, клиент будет получать изменения значения этого топика.

Брокер по сути служит эдаким key-value хранилищем, который бродкастит изменения значений топиков тем, кто на них подписался. Эдакая шина данных. Пространство имён одно, общее, оттуда и растёт иерархичность названий топиков.

Топики бывают read-only, write-only, read-write. Способа определить это, кроме как прочитать документацию производителя устройства вроде нет. По сути оно означает “пишет устройство в этот топик”, “читает ли устройство то, что пишут ему в этот топик”. Read-write переключатели режима удобны, но писать желаемую температуру в текущую реальную температуру, которая приходит на датчик было бы странно.

Бывает так, что за один параметр отвечают несколько топиков - один за чтение, другой за запись. Например /device/target_temperature - будет присылать, какая сейчас желаемая температура, но установить новую нужно через /device/target_temperature/set.

Бывает что один топик отвечает за несколько параметров (см. JSON ниже).

Формат топиков - дело вендора. Из вариантов, которые я видел:

  1. Скалярные - числа integer (скорость рекуператора), float (желаемая температура), строки (название режим работы). Bool значения как правило выражаются в строковом представлении, а-ля "on" или "off", которое захотел вендор. Иногда вместо "on" может быть что-то типа "heat".
  2. JSON. Ну типа, а чего бы и не отправить одним сообщением всё, что нужно от устройства: {"state": "heat", "temperature": 28}

Безопасность

Две составляющие безопасности в MQTT:

  1. Идентификация брокера с помощью TLS. Хз как использовать в домашних условиях с самоподписными сертификатами. Всё упирается в то, как добавить свой корневой сертификат в устройства, к которым толком доступа нет, кроме простенького веб-интерфейса. Если игнорировать сертификат, но использовать хоть шифрование, то сидя сбоку нельзя будет легко подслушивать взаимодействие брокера и клиента, но как по мне это херня.
  2. Аутентификация по логину и паролю. Как она работает без шифрования - хз. Можно использовать анонимный доступ. Но в таком случае, любое устройство в той же сети может гадить в ваш умный дом.

В какие-либо ACL, типа “вот это устройство может писать только в этот раздел дерева топиков” не вникал, может есть такое. Я выбрал изоляцию от пользовательской сети с помощью отдельного VLAN, файрвола и надежды, что рекуператоры не взломают тёплые полы.

Отладка

Если нужно просто посмотреть, что вообще ходит в MQTT-брокере - в Linux есть отличная графическая утилита для этого - mqtt-explorer.

Реализации MQTT-клиентов

Python. Я думал их сильно больше, но всё сводится к синхронному paho-mqtt и асинхронной обёртке над ним - aiomqtt. Им и пользуюсь. Как этим добром пользоваться можно подсмотреть в исходниках моего проекта - в основном файл automator.py. Там есть две asyncio.Task:

  • schedule - обработчик правил для смены режимов по расписанию.
  • feedback - приём сообщений не инициированных самой системой управления (смены режимов с помощью нажатий клавиш на приборе или его пульте);

Устройства

Найти умное устройство, которое поддерживает работу с локальным MQTT-брокером по Wi-Fi относительно сложно. С кем мне повезло:

  • Lytko - терморегуляторы. Пока использовал только Lytko 101, но своего часа на даче ждут два Lytko 100.
  • Vakio - рекуператоры (вентиляция). Никаких нареканий. В будущем хочу ещё два вентилятора поставить в туалет (чтобы автоматически выключался программно) и в ванную комнату (чтобы автоматически включался по уровню влажности). На даче уже установлены, но не обкатаны.
  • Vaisterm - термометр без каких-либо действий. Просто датчик за 1500р.
  • Yeelight - светильники. У них MQTT нет, но есть TCP (даже не HTTP) API. Получать состояние не получается, но кого это останавливало. В свою систему прикрутил их костылём, накрутил логику:
    • если личный комп включен, у светильника включено питание и уже поздно и темно - включить свет;
    • если комп выключили, а светильник должен гореть - выключить его;
    • если уже 22:50 - пора идти спать, выключаем свет”.