[Из песочницы] Opensource контроллер умного дома на базе Arduino Mega 2560 с поддержкой MQTT, DMX-512, 1-Wire, Modbus и Openhab

geek.png

Доброе время суток, уважаемым Хабравчанам.

Сегодня я решился вынести на суд общественности проект, работу над которым вел на протяжении последней пары лет: «LightHub». То, что получилось в итоге, можно назвать, пожалуй, самым дешевым решением для создания Умного дома, которое, тем не менее, умеет:

  • Управлять освещением и силовыми устройствами (Как реле так и диммеры DMX-512 и Modbus RTU)
  • Управлять теплыми полами (в качестве термодатчиков используются полтора десятка дешевых DS18B20, разведенных по квартире)
  • Управлять задвижками вентиляции/кондиционера через преобразователи ШИМ→0…10В
  • Управлять самодельной системой приточной вентиляции. (об этом, если повезет, в следующей статье)
  • Многое такого, о чем я изначально не задумывался, просто в силу того, что контроллер получился абсолютно открытым, гибко конфигурируемым, и прекрасно дополняющим Опенсорсные решения Openhab+Mosquitto+NodeRed


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

На выход — например, такие вот релейные модули, DMX, Modbus переферия.

Контроллеры конфигурируются при помощи JSON файлов, которые при старте контроллера загружаются по http (далее, конфиг можно сохранить в NVRAM через Serial CLI). Ну и, конечно, все это управляется системой Openhab 2, через штатное мобильное приложение.
Задачи «малой автоматизации» решены как при помощи штатных openhab rules (прямо скажем, не очень удобных), так и при помощи NodeRed. (По поводу NodeRed вот статья, которая прекрасно описывает пример автоматизации.)

Исходники, вместе с примерами конфигов, выложены на GIThub, описание понемногу выкладываю на сайте проекта. Соответственно, более полная история под катом.
Началось все с ремонта в квартире, в процессе которого я решил сделать дом прилично умнее.
При этом, тратить серьезные деньги на «Брендовое» решение Умного Дома, откровенно, не хотелось. Тем более, что многие «Серьезные» решения использовали закрытые стандарты и интегрировались друг с другом при помощи откровенных костылей.

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

В качестве Hardware для контроллера я выбрал Arduino Mega 2560+Ethernet shield.

Копеечная цена, огромное кол-во портов ввода вывода, 4 аппаратных UART, приличный размер NVRAM, который мне пока удалось только на 30% занять прошивкой и в который умещается с запасом весь конфиг, причем, прямо в формате JSON подтвердили разумность выбора.

После обновления Bootloader, и корректировки библиотеки Ethernet удалось успешно задействовать аппаратный Watchdog процессора, что добавило решению «промышленности», а мне спокойствия, хотя, прошивка и без этого не была замечена в зависании.

Отсутствие на контроллере какой либо операционной системы позволяет считать его «системой реального времени», что позволяет, например, программно генерировать тот же сигнал DMX.
Узкое место — размер RAM. И это не позволяет использовать всю необъятную переферию контроллера.

Но у меня, например, задействованы два контроллера. Они разнесены по квартире (это позволяет, минимум, не тянуть все провода в одну точку и достигнуть линейного масштабирования системы)
Для взаимодействия друг с другом, а также, с системами Openhab и NodeRed используется MQTT брокер Mosquitto.

В качестве драйвера шины 1-wire я использовал чип (I2C драйвер) ds2482–100 с Aliexpress, который при цене в 60 руб обеспечивает устойчивую работу с шиной до 100М

Для гибкого конфигурирования устройства я доработал библиотеку AJSON для Arduino, таким образом, что она имеет возможность как загружать объект по http так читать и записывать объект из/в NVRAM контроллера. Форк доступен на Github

Serial CLI при создании нового контроллера надо прописать в NVRAM уникальный MAC адрес. Именно MAC является ключом, по которому изначально загружается конфигурация c http сервера.

Наличие в проекте квартиры большого кол-ва светодиодного освещения, также, требовало какого-то разумного управления.

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

Подумав, я заказал на АliExpress пару плат, каждая из которых может управлять 30-ю каналами LED с номинальным током до 2А на канал.

Для того, чтобы увеличить максимальную мощность одного канала, я перешел со светодиодных лент на 12В на 24В ленты. При этом, полноценно осветить комнату около 16–18 кв. м оказалось возможным при помощи 4-х ключей. БОльшие по площади помещения пришлось зонировать — в гостиной подключил независимо 4 ленты по 5 м, задействовав при это 16 каналов.

Для синхронного управления всей комнатой, пришлось придумать тип канала «группа»

Вот как выглядит описание гостиной в JSON конфиге:

 "kuh":[7,["kuhline","kuhfre","kuhwork","kuhwin"]],
 "kuhwin":[1,5],
 "kuhline":[1,13],
 "kuhfre":[1,25],
 "kuhwork":[1,1],


Первый элемент массива — тип канала, второй — параметр канала, который может являться массивом.

Для элемента типа 7 (группа) — аргументом является массив элементов, входящих в группу.
Рекурсия, конечно же, поддерживается.

Для элемента типа 1 (лента RGBW) — аргумент — базовый DMX адрес канала.

Со стандартной библиотекой EasyDMX платы не заработали сразу. Как оказалось, китайский LED контроллер не переваривал 2ms задержку между фреймами DMX (interframe delay). Несложная модификация кода библиотеки (сокращение цикла в два раза) помогла.

Форк библиотеки на GitHub-е


Далее — я установил канальный кондиционер, который в состоянии как нагреть так и охладить всю квартиру. Чтобы как-то распределять холод и тепло по спальням, я установил сервоприводы с управлением сигналом 0–10В. Угол открытия задвижек регулируется автоматически при помощи NodeRed, в котором для этого нашелся удобный PID регулятор.

Подробности по кондиционированию
К сожалению, не удалось найти приводов воздушных заслонок с ШИМ или каким-то цифровым входом, поэтому на том же AliExpress были приобретены 4 преобразователя ШИМ в стандартный аналоговый сигнал 0…10В

Преобразователи великолепно заработали сразу, пришлось только перепрограммировать таймер ШИМ выходов для того, чтобы задать подходящую частоту.

Ниже пример перепрограммирования таймеров 3 и 4 (отвечают за pin-ы 2, 3, 5, 6, 7, 8 Arduino Mega на частоту 4000Гц)

        pinMode(iaddr,OUTPUT);
        //timer 0 for pin 13 and 4
        //timer 1 for pin 12 and 11
        //timer 2 for pin 10 and 9
        //timer 3 for pin 5 and 3 and 2
        //timer 4 for pin 8 and 7 and 6
        int tval = 7;             // 111 in binary - used as an eraser
        TCCR4B &= ~tval;   // set the three bits in TCCR2B to 0
        TCCR3B &= ~tval;   
        tval=2;  //prescaler = 2 ---> PWM frequency is 4000 Hz
        TCCR4B|=tval;
        TCCR3B|=tval;        
        analogWrite(iaddr,k=map(Value,0,100,0,255));
      


Далее, я начал искать WiFi контроллеры теплых полов. Нашел, в целом, неплохое устройство стоимостью около 6 тыс руб от Теплолюкс, но оно имело некоторые существенные для меня недостатки.

Несмотря на наличие мобильного приложения, протокол управления был закрыт. Я провел некоторый реверс-инженеринг, который показал, что, теоретически, протокол можно расшифровать. Возможно, я бы этим и занялся, но обнаружил, что без переустановки подразетников сие устройство не устанавливается в один ряд с выключателями. Это определило судьбу устройства: продав его, я реализовал функционал простого термостата на своем контроллере, сэкономив почти 30 тыс руб на 5-ти теплых полах.

Получилось следующее:
  • Все управление — локально на контроллере и независимо от домашней ИТ инфраструктуры
  • Используются измерения с 1-wire термодатчиков. Если датчик долгое время не может быть опрошен — нагреватель отключается.
  • Через MQTT можно включить/выключить теплый пол и задать его температуру. Соответственно, полы управляемы через интерфейсы и мобильное приложение Openhab
  • Я не стал реализовывать хитрые сценарии и расписания на контроллере. При желании, это легко реализуется правилами Openhab или Node-Red. Я ограничился только отключением устройств, когда люди покидают дом.

Вот пример конфига для одного теплого пола:
"ow":{
                 "2807FFD503000036":{"emit":"t_bath1","item":"h_bath1"}
        },
  "items":{
        "h_bath1":[5,24,33],
         },


Данные при опросе термометра OneWire с указанным адресом передаются на шину MQTT в топик t_bath1, а также, внутри контроллера, объекту h_bath, имеющему тип №5 (термостат), реле подключено к pin#24 контроллера, уставка — 33 градуса (можно корректировать по MQTT)


Входы устройства

В конфиге для каждого входа можно задать как передачу команды локальному объекту так и выдачу команды в MQTT топик. Причем, отдельно как на условное «нажатие» кнопки так и на «отпускание».

Примеры:
"in":{
          "41":{"emit":"/myhome/in/all","scmd":"HALT","rcmd":"REST"},
          "38":{"item":"spots_en"},
          "37":{"emit":"/myhome/in/light","scmd":"ON","rcmd":"OFF"},
          "40":{"emit":"/myhome/in/gstall","scmd":"TOGGLE","rcmd":"TOGGLE"},
          "35":{"emit":"/myhome/s_out/water_leak"}
         }


Pin 41: Геркон на замке входной двери — при запирании — выдаем в топик /myhome/in/all команду HALT, при отпирании — команду REST.

У меня это приводит к полному «засыпанию» и «просыпанию» дома. К слову — команды не входят в стандартный набор OpenHab, но получились крайне удобны — HALT — выключает устройство, REST — восстанавливает параметры устройства до последнего значения (цвет, яркость, температура), но только для того устройства, которое было выключено командой HALT, а не OFF. Это позволяет не включать то, что было выключено на момент покидания дома.

Pin 38: Просто обычный выключатель света. При замыкании — выдает (по умолчанию) команду ON, при размыкании — команду OFF. Эти значения передаются объекту «spots_en». Понятно, что состояние обьекта можно изменить с мобильного приложения. В этом случае, выключатель, как бы, остается, например, во включенном положении, но свет выключен.

Для любителей классических проходных выключателей, подойдет синтаксис Pin 40:
И при включении и при выключении выдается команда TOGGLE (тоже, кстати, новая, относительно OpenHab), меняющая положение Вкл-Выкл устройства (в данном примере, лампа управляется не локально, а через MQTT другим контроллером).

Если это не перекидной выключатель, а кнопка — достаточно просто скорректировать «rcmd»:» — при этом команда на переключение будет выдаваться только при нажатии.


А, ну и почти забыл описать DMX-IN — вход, ради которого, можно сказать, я и начинал эту разработку.

На рынке масса удачных с дизайнерской точки зрения и, в целом, эргономичных DMX контроллеров светодиодных лент.

Один из таких (сенсорную панель) я и купил в самом начале для экспериментов с DMX. Все хорошо, но архитектура DMX не предусматривает никакого управления из более чем одного места. Существует один Мастер, который постоянно транслирует в шину яркости каналов. Но в этом проекте данная проблема решена. Контроллер LightHub отслеживает изменения каналов DMX на входе, подключенном к сенсорной панели. Если они изменяются — транслирует изменения на выход (с маппингом на сконфигурированные устройства, в том числе, на группы светодиодных лент).

Пока ничего не меняется — устройства нормально управляются удаленно. Стоит сенсорной панели поменять значения яркости каналов — эти изменения транслируются на DMX выходы.

Как не странно, этот костыль получился вполне эргономичным. Хотя, как показал опыт, мы все реже используем сенсорную панель и все чаще смартфоны для управления устройствами.

Заключение

К сожалению, в одной статье невозможно описать все нюансы, заложенные в разработку. Например, совсем за кадром осталась тема подключения Modbus устройств, их пуллинг и синхронизация локального состояния устройства с системой Умного Дома, интеграция с простой приточной установкой. Ну и, возможно, сравнение с существующими системами близких классов, такими, например, как MegaD-328, AMS и, даже, WirenBoard. Возможно, если будет заинтересованность — продолжу.

Относительно проекта LightHub — при всей дешевизне, контроллеры оказались вполне рабочим решением. Честно говоря, я сам не верил, что на основе Arduino можно создать стабильно работающую систему, но, по-моему, это удалось.

Конечно, надо многое еще доделать: полностью уйти от харткода (осталось совсем чуть-чуть), немного и местами почистить и рефакторить код, тщательно документировать проект, развести печатную плату (сейчас интерфейсные Шилды спаяны просто на основе макетных плат и содержат три MAX-485 — (DMX-IN, DMX-OUT, Modbus) и 1-Wire мост) — и это станет, по сути, очень бюджетным готовым решением.

Понятно, что надо расширять функционал. Как минимум, в направлении беспроводных датчиков/устройств. (Хотя, например, ZWave и так сейчас можно использовать через стандартные биндинги Openhab).

Возможность подключения, например, бюджетного NooLight, вероятно, неплохая идея.
Возможно, подумаю над миграцией на ESP-8266 для расширения RAM, хотя, уход на WiFi с проводного подключения к LAN мне не нравится с точки зрения надежности. Да и ESP не обладает такой богатой переферией как Arduino Mega.

Также, полезно было бы сделать конфигурирование и запуск контроллера более User Friendly (визуальные конфигураторы и пр.). При этом, сознательно не хочется превращать контроллер в вебсервер с файлами/картинками, AJAX и пр. На мой взгляд, это уже должно являться прерогативой сервера. Хотя бы на основе Raspberry.

Но поскольку проект абсолютно Опенсорсный — возможны разные варианты, присоединяйтесь.
Также, с нетерпением ожидаю ваших отзывов.

© Geektimes