Привет, Хабр! Сегодня мы поговорим о том, как сделать систему управления отоплением в загородном доме своими руками, используя легкодоступные микроконтроллеры и свободное ПО… причем сделать её так, чтобы можно было запрограммировать работу нужных устройств при помощи моего любимого 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-прототип, реализовав: 

  1. сбор данных на уровне датчиков и микроконтроллеров;

  2. подключение к сети интернет посредством Yandex Cloud IoT.

Далее, поток нескончаемых дел, к сожалению, навалился на меня и я так и не успел реализовать фронтальную часть проекта. Однако, успешная реализация «базы» показала мне, что проект вполне может быть доведен до конца. Возможно чуть позже я выпущу обновление статьи, в котором смогу представить «батин умный дом» целиком. А пока вы можете посмотреть, как выглядит микроконтроллер в рабочем состоянии на этом видео

Спасибо за внимание и до новых встреч! Буду очень рад вашим комментариям.

Комментарии (13)


  1. SuperTEHb
    00.00.0000 00:00

    Так esp8266 помощнее атмеги будет. Зачем там ардуина?


    1. SimonBryatov Автор
      00.00.0000 00:00

      С Arduino Uno был небольшой опыт, а на алихе наткнулся на такой "комбайн" 2 в 1 :) Решил взять ради экспериментов и тут понеслась... :)

      Скажу честно - я нубик в этом деле, поэтому описал свой первый опыт в этой статье


      1. SuperTEHb
        00.00.0000 00:00

        Лично мне нравится прошивка NodeMCU. Пишется скрипт на LUA, который просто выполняется потом. А можно прямо на ходу в ЕСПху отправлять команды и они будут сразу исполняться. Так что осмелюсь порекомендовать к ознакомлению.


        1. SimonBryatov Автор
          00.00.0000 00:00

          Благодарю за совет! Надо чекнуть на новом пет-проекте)


    1. iig
      00.00.0000 00:00

      Во-первых, нам не удалось подружить напрямую температурный сенсор DHT с ESP8266

      А так, поддерживаю. Можно было просто взять не самый дешманский сеносор, например ;) Или другую прошивку. Это дешевле чем ещё один микроконтроллер.

      НО если xочется именно в гамаке и именно на JS..


      1. SimonBryatov Автор
        00.00.0000 00:00

        Тут стоит только в это окунуться и глаза уже начинают разбегаться ))


        1. iig
          00.00.0000 00:00

          IMHO для esp8266, если хочется мигания лампочками и прочих закатываний солнца руками - arduino лучше всего. Доступны все 100500 либ для чего угодно.

          Или взять готовую прошивку типа ESPEasy.

          Выпиливать кастомный троллейбус на lua/js/python.. Тоже можно конечно.


          1. SimonBryatov Автор
            00.00.0000 00:00

            Прикольно. Не натыкался на такую прошивку. Спасибо за наводку)


  1. little-brother
    00.00.0000 00:00
    +4

    Иллюстрации - огонь :) А не как обычно у большинства - корпоративные гипертрофированные люди-уроды.


    1. SimonBryatov Автор
      00.00.0000 00:00

      Спасибо! Иллюстратор хорошо постарался картинки из моего более примитивного по визуалу доклада "развеселить", нам очень приятно)


  1. IgorKKK
    00.00.0000 00:00
    +1

    Не стоит применять этот датчик, ибо он игрушка. Даже если проект игрушечный.

    В любой момент, но после привыкания к тому, что у вас есть данные, этот датчик выйдет из строя.

    Датчик надо применять ds18b20, что на длинном проводке имени OneWire, таких датчиков можно насажать параллельно штук сто и знать температуру как до так и после, а ещё затем.

    Микроконтроллер от итальяно-китайских товарищей здесь можно потерять, оставив лишь чистый китайский esp8266, коего хватит с запасом.

    За лирическую литературную часть жирный плюс. Остальное - нубам читать не рекомендовал бы.


    1. SimonBryatov Автор
      00.00.0000 00:00
      +1

      Спасибо за комментарий) Я сам нуб, так что любая конструктивная критика только приветствуется!


      1. IgorKKK
        00.00.0000 00:00

        Велкам в поиск "Nodemcu Lua азы". Там, уверен, для Вас много интересного. Lua - это JS, почти. Но эта система проработана поглубже, чем те, на которые Вы ссылаетесь.