В дневное время я пишу много сложного кода на C++, который расширяет возможности высокопроизводительных приложений для встраиваемых устройств. Иногда мне приходилось работать с некоторыми из этих так называемых coнеподключенных устройств. Категория устройств, которые все пытаются протолкнуть на рынок, независимо от того, действительно они полезны или нет.

Перед каждым встраиваемым сетевым проектом стоят большие технические проблемы, которые разработчики пытаются решить: обновления программного обеспечения, безопасность, надежность и простота использования. Поэтому в свободное время я начал свой собственный проект IOT, чтобы увидеть, смогу ли я без ограничений найти несколько элегантных технических решений для преодоления этих проблем. Вот что я придумал:

ЧикСреда, созданная в GO, которая позволяет создавать монолитные приложения Интернета вещей, просто собирая или создавая компоненты, называемые обработчиками. Платформа предоставляет публикацию, основанную на структуре связи процесса, а также ответ на запрос, такой как структура, для связи с другим устройством по сети и интерфейс для хранения/извлечения данных. Фреймворк использует Json в качестве формата для сообщений и хранимых данных.

Почему ИДТИ?

GO не так популярен на встроенных устройствах. Подавляющее большинство встроенных проектов, над которыми я работал в дневное время, использовали C++, но у GO есть несколько преимуществ, которые значительно упрощают работу:

  • Это достаточно быстро: это не так быстро, как C++, но в большинстве случаев это достаточно быстро.
  • На GO проще и быстрее писать сложные приложения на GO, а не чем на C++, потому что в Go есть сборщик мусора, а управление памятью осуществляется «вспомогательно». знаю, что в наши дни C++ значительно улучшился, но он не должен быть таким простым языком, как GO.
  • Он статически связан: каждая библиотека связана с исполняемым файлом, и это просто выбрасывает из окон все разочарования, с которыми каждый день сталкивается разработчик встроенного C++: отсутствие стандартных наборов инструментов, кошмары с динамическим связыванием и  при разработке для встроенных устройств - еще хуже ситуация.
  • Для этого не требуется встроенный SDK: компилятор GO может выполнять кросс-компиляцию для широкого спектра архитектур. Предположим, вы хотите выполнить кросс-компиляцию для вашего raspberrypy: просто введите следующую команду: GOOS=linux GOARCH=arm GOARM=6 go build и все готово, как это просто, вместо того, чтобы проводить часы перед ПК, который просто компилирует встроенный SDK yocto, надеясь, что это последний раз, когда вы бежали bitbake

Архитектура

Фреймворк позволяет создавать монолитные приложения путем создания экземпляра элемента Controller. Он действует как шина для сообщений и оркестратор для различных строительных блоков, называемых обработчиками. Контроллер управляет временем жизни обработчиков, предоставляет им канал для связи друг с другом и позволяет отправлять сообщения во внешний мир через Remote.

Handler — это интерфейс, содержащий одну функцию: Run. Он выполняется в горутине и может общаться и получать сообщения через Controller API. Наличие нескольких горутин помогает приложению хорошо масштабироваться на различном оборудовании, даже будучи монолитным. Вот пример обработчика

Пульт взаимодействует с внешним миром и мобильным приложением (да, оно есть) с потоком данных, отправляемым через постоянное соединение TLS. на сервере работает то же программное обеспечение, что и на клиенте, но с другими обработчиками. В настоящее время предоставляется только обработчик маршрутизации, который позволяет пересылать сообщения целевому клиенту на основе uuid получателя сообщения. Я выбираю постоянный поток TCP вместо более распространенного http REST API, потому что мне очень нравится, когда свет сразу же реагирует на команды, которые я выдаю из мобильного приложения.

В дополнение к двоичному файлу для программного обеспечения должен быть предоставлен файл конфигурации Json. Если его нет, приложение при запуске создаст эталонное. Файл содержит данные конфигурации для каждого обработчика, а также раздел хранилища для хранения данных времени выполнения, таких как таймеры. Это позволяет упростить резервное копирование или миграцию на другое оборудование, поскольку необходимо скопировать только один файл.

Использование Only Json в качестве формата хранимых данных и формата данных полезной нагрузки сообщения очень помогло, потому что это удобочитаемый формат, и нет необходимости писать классы адаптера для преобразования данных. В качестве плюса GO имеет отличные встроенные json API.

Статус проекта и план

В настоящее время я использую клиент, написанный с помощью фреймворка на старом устройстве MIPSel, которое управляет моим садовым освещением. Я также поставил его на ноль RaspberryPi, чтобы переключить садовое освещение и систему орошения моих родителей. Затем у меня есть дешевый VPS, который запускает серверное приложение для каждого устройства и выполняет пересылку сообщений. Чтобы контролировать всю систему, я сделал неполное приложение Qt/QML для Android, которое выполняет основные функции, такие как установка таймеров, включение/выключение чего-либо и обновление удаленного устройства при выходе новой версии.

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

Помимо этого, я хочу добавить больше обработчиков для таких вещей, как новые протоколы и доступ третьих лиц, таких как Google home и Apple HomeKit, и немного полюбить мобильное приложение, но, поскольку это в основном проект в свободное время, я сначала сделаю то, что более интересно, и что мне действительно нужно второе.

В заключение я думаю, что GO может стать взрывом в мире встраиваемых систем. И эта структура — мое доказательство того, что это выполнимо. Надеемся увидеть некоторые инновации в области встраиваемых систем в ближайшие годы.