Mqtt
Уже год я разрабатываю домашнюю автоматизацию. За основу взял 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 ниже).
Формат топиков - дело вендора. Из вариантов, которые я видел:
- Скалярные - числа integer (скорость рекуператора), float (желаемая температура), строки (название режим работы). Bool значения как правило выражаются в строковом представлении, а-ля
"on"
или"off"
, которое захотел вендор. Иногда вместо"on"
может быть что-то типа"heat"
. - JSON. Ну типа, а чего бы и не отправить одним сообщением всё, что нужно от устройства:
{"state": "heat", "temperature": 28}
Безопасность
Две составляющие безопасности в MQTT:
- Идентификация брокера с помощью TLS. Хз как использовать в домашних условиях с самоподписными сертификатами. Всё упирается в то, как добавить свой корневой сертификат в устройства, к которым толком доступа нет, кроме простенького веб-интерфейса. Если игнорировать сертификат, но использовать хоть шифрование, то сидя сбоку нельзя будет легко подслушивать взаимодействие брокера и клиента, но как по мне это херня.
- Аутентификация по логину и паролю. Как она работает без шифрования - хз. Можно использовать анонимный доступ. Но в таком случае, любое устройство в той же сети может гадить в ваш умный дом.
В какие-либо 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 - пора идти спать, выключаем свет”.