Привет, Хабр! Сегодня мы поговорим о том, как сделать систему управления отоплением в загородном доме своими руками, используя легкодоступные микроконтроллеры и свободное ПО… причем сделать её так, чтобы можно было запрограммировать работу нужных устройств при помощи моего любимого JavaScript. Под катом — разбор трех вариантов решения этой задачи (включая тот самый, который я выбрал), а также масса рассуждений о преимуществах и недостатках данного подхода. Всех любителей сделайсамов и очумелых ручек приглашаю под кат.
Я понимаю, что в некоторых регионах зима уже подходит к концу (а в местах обитания некоторых хабрачитателей она вообще не начинается, если иметь в виду настоящую русскую зиму). Но это никак не отменяет того факта, что у каждого ИТ-шника рано или поздно возникает желание наладить удаленный мониторинг и управление отоплением (а в теории — и другими устройствами), которые работают в загородном доме.
Тут вы можете сразу же сказать, что систем управления умным домом и автоматизации интернета вещей существует великое множество. И совершенно не обязательно изобретать велосипед. Да, это так. Изобретать не обязательно, но очень хочется! К тому же для тех, кому доставляет удовольствие делать все самостоятельно, это сулит значительную экономию бюджета, а также исключительно широкие возможности самостоятельной тонкой настройки всего-чего-угодно. Так что поехали!
Постановка задачи
Есть у моего бати загородный дом. И когда он сидит зимой в своей квартире, ему хочется узнать: «а какая там температура на даче, не перемерзнет ли чего, включился ли обогреватель, когда нужно?» И чтобы сделать это, нужно как-то собирать информацию о температуре в помещении через микроконтроллер и пробрасывать все это через открытый интернет. Так можно издалека оценивать ситуацию и покидать свою уютную квартиру зимой только в случае экстренной необходимости.
В качестве основы проекта выбираем доступный микроконтроллер Arduino с модулем Wi-Fi (все-таки батин дом стоит не в глухой деревне, и интернет у нас подведен, подключение к нему относительно стабильное). Также докупаем совместимый и относительно дешевый датчик температуры/влажности DHT11. Ну и мини ЖК-экран в придачу, чтобы можно было локально вывести/посмотреть состояние в помещении («а почему бы и да», ведь можно дополнительно развлечься с настройкой сего «зоопарка»).
Решить задачу физического подключения контроллера к датчикам температуры/влажности и ЖК-дисплея достаточно несложно — просто втыкай провода в правильной последовательности и позаимствуй со стэковерфлоу какой-нибудь популярный блок кода на языке С (основной ЯП для контроллеров Arduino). Другое дело — попробовать подружить все это с языком JS, добавив возможность общения по открытой сети интернет! Задачка становится интереснее!
Приступаем к делу
Чтобы найти свое решение задачи, я выбрал знакомый мне контроллер Ardiuino Uno + Wi-Fi-модуль ESP8266, потому что с ними у меня уже был опыт базовых экспериментов с лампочками. Мы пробовали программировать как на C, так и на JS их включение/выключение, и выглядело все это очень даже неплохо. Можно сказать, воодушевило на новые эксперименты.
В качестве платформы для передачи данных я решил попробовать Yandex Cloud IoT Core MQTT Broker.
Путь для JS
Далее возникает вопрос: «Как именно добиться возможности использовать JavaScript для программирования этого контроллера и режимов его работы?» Я сознательно выбрал именно его, потому что имею более обширный опыт в данном ЯП, нежели в С, к тому же гуглинг показал, что использование JS в качестве основы является вполне рабочим решением.
Спойлер. в итоге я пришел к выводу, что лучше всё-таки использовать язык С, так как он является более «правильным» инструментом для выполнения моей задачи, но в этом случае рубрика бы не называлась «очумелые ручки» :)
1. Протокол Firmata + библиотека Johny-Five npm
Это неплохое решение. Реализованная на С библиотека Firmata позволяет легко общаться с контроллером через ПК. А Johny-Five — это абстракция, которая позволяет общаться с протоколом Firmata уже на JS.
Среди плюсов этого подхода — огромное количество дополнительных утилит, уже реализованная поддержка множества IoT-устройств, а также «наичистейший Node JS» в плане программирования прикладной логики на основе полученных данных от контроллера и настройки разнообразных сценариев. Короче, рай для JS-фуллстеков.
Однако есть и минусы. И самый большой из них — необходимость использовать локальное устройство-брокер для коммуникации с внешним миром, на котором и развернется NodeJS-сервер. Проще говоря, нужен какой-то мини-ПК под боком. В моем случае ничего такого в свободном доступе не нашлось. И мне пришлось просто откинуть этот вариант.
2. Espruino
Если еще не знакомы — знакомьтесь! Espruino — это целая экосистема для программирования микроконтроллеров на JavaScript. У нее, кстати, немало адептов в глобальной сети. В Espruino входит прошивка для микроконтроллеров с интерпретатором JS, а также среда разработки Espruino Web IDE. Еще в интернете можно купить платы Espruino и совместимые с ними устройства. Да и вообще вся документация доступна на www.espruino.com, заходите, не стесняйтесь.
Плюсов у решения поистине множество. В нем используется настоящий интерпретатор JS (да, с ограничениями, но незначительными). Уже создано немало библиотек для самых разных задач, имеется возможность подключения их через CommonJS.require(). Среда разработки IDE удобна и позволяет обновлять скрипты ОТА. Системой поддерживается достаточное количество устройств (хотя и не так много), но самое главное, что построенное на базе Espruino решение может работать автономно, ему не обязательно постоянное соединение с брокером-мастером (в отличие от Firmata). Кстати, стоит добавить, что в данном варианте мы используем как основной «мозг» системы не контроллер Arduino Uno, а конкретно его Wi-Fi-модуль ESP8266 (отсюда и название ESPruino). В моем случае, заказанная плата с aliexpress являлась платой 2 в 1: Arduino UNO + Wi-Fi-модуль ESP8266.
Но, как обычно, есть и подводные камни. Для нашего проекта их было два. Во-первых, нам не удалось подружить напрямую температурный сенсор DHT с ESP8266. И даже при том, что на форумах многие жаловались на эту проблему и были предприняты коллективные попытки что-то с этим сделать, побороть беду так и не вышло. Пришлось «костылить» проброс данных от Arduino UNO в ESP8266 через дополнительный провод. А во-вторых, оказалось, что соединение TLS пока что поддерживается только двумя платами (и, к сожалению, эта проблема оказалась фатальной). Наверное, ситуация скоро изменится, об этом также писали на форуме разработчики…но пока так. Яндекс Cloud IoT работает как раз через TLS, так что пускаем скупую слезу и отбрасываем Espruino тоже.
3. Mongoose OS + библиотека mJS
Это решение отличается от предыдущих и работает немного иначе. Мы устанавливаем специальную операционную систему Mongoose OS (не путать с Mongoose в Node JS для Mongo DB!) для работы с контроллерами низкого энергопотребления. А библиотека mJS позволяет использовать синтаксис JavaScript (хотя и сильно урезанный). Далее написанный код компилируется в С и загружается в Mongoose OS. Исходя из этого также имеется возможность подключать дополнительные модули-библиотеки, написанные на C и использовать их в mJS на основе абстракции интерфейсов FFI (foreign function interface).
Плюсы этого решения очевидны:
легковесная и модульная система использует мало памяти (постоянной и оперативки);
поддерживается TLS «из коробки»;
имеется возможность подключать библиотеки на C и работать с ними через прослойку FFI (foreign function interface);
кроме этого среда разработки IDE тоже очень удобна: обновления приходят «по воздуху», а автономная работа также возможна без подключения к брокеру;
имеется удобный плагин для популярной IDE VSCode.
Есть, конечно, и минусы. Так, мне пришлось пошаманить с последней версией ОС, которая не хотела вставать на ESP8266 (в итоге взял более старую, но совместимую). Также нужно было адаптироваться к более «куцому» синтаксису mJS. В нем нет замыканий, деструктуризаций, стрелочных функций, а также базовых утилит, таких как String, Array, Object и так далее. Спасибо, правда, что не вырезали JSON. Впрочем, для базовых операций и нашей конкретной задачи «мангуст» оказался вполне съедобным.
Выбираем №3 и едем
Выбор в пользу третьего варианта с Mongoose OS был предрешен, потому что, как я уже говорил, для варианта №1 я не нашел свободного устройства-брокера и решил не переплачивать за сложности. Второй вариант отпал, потому что Yandex IoT Core поддерживает только MQTTS, что заставило отказаться от Espruino — у меня было устройство, в котором поддержка TLS отсутствовала, не покупать же новое!
На самом деле, я понимаю, что вариантов решения этой задачи существует целое множество, но мне хватило этих трех. К тому же, раз один подходит, зачем копаться дальше? В конце концов, можно было вообще отбросить «танцы с бубном» вокруг JS и использовать стандартный C напрямую. Но это явно менее прикольно!
В результате я реализовал следующую схему:
-
Плата Arduino Uno (AT Mega 328P)
работает на С (собственно, немного кода на С пришлось написать всё-таки для этой связки, но это точно не "rocket science")
собирает информацию с датчика DHT11,
выводит информацию на ЖК-экран,
отправляет данные на модуль ESP8266 по UART.
-
MK ESP8266 WiFi
работает под управлением Mongoose OS и кодом, написанном на урезанном JS,
принимает информацию с Arduino Uno,
отправляет данные по MQTTS в Yandex.Cloud.
Мне удалось создать MVP-прототип, реализовав:
сбор данных на уровне датчиков и микроконтроллеров;
подключение к сети интернет посредством Yandex Cloud IoT.
Далее, поток нескончаемых дел, к сожалению, навалился на меня и я так и не успел реализовать фронтальную часть проекта. Однако, успешная реализация «базы» показала мне, что проект вполне может быть доведен до конца. Возможно чуть позже я выпущу обновление статьи, в котором смогу представить «батин умный дом» целиком. А пока вы можете посмотреть, как выглядит микроконтроллер в рабочем состоянии на этом видео.
Спасибо за внимание и до новых встреч! Буду очень рад вашим комментариям.
Комментарии (13)
little-brother
00.00.0000 00:00+4Иллюстрации - огонь :) А не как обычно у большинства - корпоративные гипертрофированные люди-уроды.
SimonBryatov Автор
00.00.0000 00:00Спасибо! Иллюстратор хорошо постарался картинки из моего более примитивного по визуалу доклада "развеселить", нам очень приятно)
IgorKKK
00.00.0000 00:00+1Не стоит применять этот датчик, ибо он игрушка. Даже если проект игрушечный.
В любой момент, но после привыкания к тому, что у вас есть данные, этот датчик выйдет из строя.
Датчик надо применять ds18b20, что на длинном проводке имени OneWire, таких датчиков можно насажать параллельно штук сто и знать температуру как до так и после, а ещё затем.
Микроконтроллер от итальяно-китайских товарищей здесь можно потерять, оставив лишь чистый китайский esp8266, коего хватит с запасом.
За лирическую литературную часть жирный плюс. Остальное - нубам читать не рекомендовал бы.
SimonBryatov Автор
00.00.0000 00:00+1Спасибо за комментарий) Я сам нуб, так что любая конструктивная критика только приветствуется!
IgorKKK
00.00.0000 00:00Велкам в поиск "Nodemcu Lua азы". Там, уверен, для Вас много интересного. Lua - это JS, почти. Но эта система проработана поглубже, чем те, на которые Вы ссылаетесь.
SuperTEHb
Так esp8266 помощнее атмеги будет. Зачем там ардуина?
SimonBryatov Автор
С Arduino Uno был небольшой опыт, а на алихе наткнулся на такой "комбайн" 2 в 1 :) Решил взять ради экспериментов и тут понеслась... :)
Скажу честно - я нубик в этом деле, поэтому описал свой первый опыт в этой статье
SuperTEHb
Лично мне нравится прошивка NodeMCU. Пишется скрипт на LUA, который просто выполняется потом. А можно прямо на ходу в ЕСПху отправлять команды и они будут сразу исполняться. Так что осмелюсь порекомендовать к ознакомлению.
SimonBryatov Автор
Благодарю за совет! Надо чекнуть на новом пет-проекте)
iig
А так, поддерживаю. Можно было просто взять не самый дешманский сеносор, например ;) Или другую прошивку. Это дешевле чем ещё один микроконтроллер.
НО если xочется именно в гамаке и именно на JS..
SimonBryatov Автор
Тут стоит только в это окунуться и глаза уже начинают разбегаться ))
iig
IMHO для esp8266, если хочется мигания лампочками и прочих закатываний солнца руками - arduino лучше всего. Доступны все 100500 либ для чего угодно.
Или взять готовую прошивку типа ESPEasy.
Выпиливать кастомный троллейбус на lua/js/python.. Тоже можно конечно.
SimonBryatov Автор
Прикольно. Не натыкался на такую прошивку. Спасибо за наводку)