Как стать автором
Обновить
541.68
Рейтинг
FirstVDS
Виртуальные и выделенные серверы в ДЦ в Москве

Программируем умный дом

Блог компании FirstVDS Open source *Разработка для интернета вещей *Интернет вещей

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

И, как и многое другое в Дивном Новом Мире Большого Брата, практически бесплатно мы получаем термостат с интеллектом кофеварки и кофеварку с интеллектом умственно отсталого муравья. С простецкой ценой в одну смертную душу в виде ваших данных. Всё это пришло вместе с лицензионными соглашениями, которые можно только посылать в филиал ада по соглашениям с Бессмертными Душами, сопроводив запиской: «Учитесь, парни…» (© Терри Праттчет, Нил Гейман — Благие Знамения.)

Не раз мы слышали новости о том, что какая-то нерадивая Алекса позвонила куда-то не туда или Алиса с Сири сливают данные одновременно товарищу майору и мистеру Смиту. Но мы не лыком шиты. У нас есть альтернативы, и с ними мы и познакомимся.

Мир IoT удивительно разнообразен. Системы разнообразны. Нужно сидеть и выбирать, будете ли вы следовать по пути Amazon, Apple, Google, Logitech или Samsung. Сами устройства разнообразны. У вас есть большое количество производителей, каждый из которых предоставляет разные протоколы и стандарты.

Каждая лампочка в доме включается через приложение, которое работает в облаке. Каждая камера снимает видео на свой облачный сервис, и каждый термостат учится по-своему. Данные текут рекой в неизвестном направлении. Да и к тому же вам уже надо покупать новый телефон, чтобы установить все приложения для контроля разнообразных роботов. А если телефон не заряжен, то и кофе вам выпить не удастся.

Можно решить вопрос консолидацией всего на одной из платформ Больших Братьев, а можно взять Ардуину и построить свой умный дом с куртизанками и преферансом. Руки у нас растут из нужного места. Писать на скриптах и питоне умеет каждый. Да и кто из нас, хабровчан, откажется от сомнительного удовольствия провести выходные, настраивая подключение кото-кормушки к камере с сенсорами (так как вы уже давно подозреваете, что ваш кот давным-давно не является единственным котом в доме)?

Итак, что делать, если вы ещё не начали писать программное обеспечение для своего дома сами?

Для начала нам нужно будет разобраться с одной достаточно простой технологией.

MQTT — Message Queuing Telemetry Transport. Протокол передачи сообщений телеметрии. В мире умных вещей на этом языке говорят достаточно многие.

Что самое интересное, протокол был разработан в 1999 году и применялся для снятия телеметрии в газопроводах. Основная идея протокола была в том, что нам был нужен легко реализуемый язык передачи данных с базовыми функциями по подтверждению доставки сообщений в пункт назначения.

В 2010 году протокол был переиздан в свободной форме, а в 2016 стал ISO стандартом.

Идея протокола достаточно проста. Всё работает по TCP/IP на порту 1883. Туда-сюда кидаются бинарные сообщения. Клиент подключается к установленному в сети брокеру, регистрируется на этом брокере и скидывает на него данные.

MQTT не создавался как протокол для настройки и работы с умным домом. Это протокол для автоматизации чего угодно. Но мы можем воспользоваться правилом пятисот дрелей и использовать MQTT как основной подлежащий протокол для всех наших умных замков, розеток и поливалок для цветов (сами устройства ищутся на различных маркетах путём добавления “MQTT” к названию устройства). Не все устройства одинаково хорошо поддерживают этот протокол. Например, если вам не повезло стать владельцем Алексы, то она вообще дружит с MQTT только после конкретной обработки напильником.

Но и не только на MQTT живёт мир. Все устройства с Амазона работают на своём протоколе. Цветные лампочки от Филипса работают на своём. Куда ни ткни — везде свой протокол. Для программирования своего дома вам придётся создавать примерно следующую архитектуру:

  1. Сеть. Самое простое — Wi-Fi. Для продвинутых пользователей шапочек из фольги можно заморочиться и найти Ethernet варианты практически любых IoT гаджетов
  2. Система-брокер. Raspberry PI или любой другой компьютер для обработки сообщений MQTT и других протоколов.
  3. Система хранения данных. Любой достаточно ёмкий диск. Объём ограничивается только вашей фантазией.
  4. Если вы собираетесь управлять своим домом с мобильного телефона — внешний IP-адрес с доменом и Let's Encrypt.

Но не бойтесь, на самом деле с нуля писать это не придётся. У нас есть большое количество уже существующих open-source проектов, которые позволяют вам просто подключать все эти устройства.

Вот три самых известных системы, на которые следует обратить внимание:

  1. OpenHab, github.com/openhab
  2. Home Assistant, github.com/home-assistant
  3. Homebridge, github.com/homebridge

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

А вот ещё куча систем, которые существуют, но до вышеописанных трёх не дотягивают.

  1. www.openmotics.com
  2. www.jeedom.com/site/en/index.html
  3. www.iobroker.net
  4. www.agocontrol.com
  5. www.domoticz.com
  6. calaos.fr/en
  7. pimatic.org
  8. www.smarthomatic.org
  9. www.mycontroller.org
  10. docs.pidome.org

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

Отдельно в этом списке идут два проекта:

  • fhem.de/fhem.html — с лицензией GNU, написанный на Perl. Этот сервер подойдёт заядлым любителям антилоп. Он упорно развивается и поддерживает множество устройств, но интерфейс оставляет желать лучшего. Плюс я не помню, когда я видел коммит на перле в последний раз.
  • www.eventghost.net — заточен для работы с Windows. Один из тех сайтов-динозавров, который по дефолту не поддерживает HTTPS. Можно просто поставить на флешку. Абсолютно бесполезен для конечного продукта, но может подойти для тестового стенда. Имеет поддержку игрового контроллера Xbox, благодаря чему можно сделать пару отличных штук с детворой.

Идея будет достаточно простой. Берём Raspberry Pi, устанавливаем на неё один из вышеописанных клиентов и начинаем разработку. Если под рукой нет малинки, то систему можно поставить на любой сервер. А если и этого нет в достаточном количестве, то ставить можно будет на обычный компьютер с докером.

Тут надо учесть вот что. Умный дом должен сам менять температуру, включать кофеварки и управлять лампочками, когда надо. Для того чтобы это «когда надо» определить, нам потребуется куча сенсоров и датчиков. А для этого нам нужно будет постоянно быть онлайн, чтобы эти датчики считывать.

Если ваши компоненты не включают в себя такие вещи, как Alexa и тому подобные гаджеты, которые требуют постоянного подключения к интернету, ваш умный дом можно будет строить на air-gapped сети.

Данные никогда не покинут вашего дома и будут храниться на вашем сервере. Но для большинства людей это сомнительное удовольствие. Полный отказ от всех интернет-зависимых сервисов вредит юзабилити.

Например, если вы решили подключить системы стриминга музыки к своему дому. OpenHab позволяет работать со Spotify, который, наконец-то, запустили в России. Более того, тот же OpenHab приучили дружить с Алисой.

Если вы хотите, чтобы ваш умный дом был доступен на смартфоне, то тут ничего не поделаешь. Всё надо будет либо подключать через интернет, либо оснащать сервер двумя сетевыми картами и выводить админку во внешний мир. Более того, вам потребуется либо выделенный адрес, либо какой-нибудь сервис для выведения этого адреса вовне.

Опять же, всё это необязательно, OpenHab может жить в пещере внутренней сети. Но если вы выводите систему вовне, то вам нужно будет учитывать два фактора:

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

Стабильный сервер с хорошим соединением позволит вашим чадам избежать стояния в холодном подъезде по 3 часа, потому что единственный физический ключ есть только у папы, а сервер решил кордампнуть по причине падения IDE жёсткого диска-пенсионера.

Итак, устанавливаем и настраиваем OpenHab. Всё просто, всё на сайте, всё по инструкции.

Что дальше?

А вот тут начинается самое интересное. Быстро читаем мануалы (мы же не те самые нерадивые админы, про которых недавно писал Григорий Остер). После чего понимаем, что попало нам в руки.

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

И вот как раз тут-то у нас начинается самая веселуха. OpenHab поддерживает из коробки NodeRed и Jython. Свой дом можно превращать в цифровую крепость на визуальном Node.js или питоне. Идея достаточно проста — у нас есть данные о состоянии датчиков. Обрабатываем эти данные скриптом и запускаем различные устройства в ответ на найденные состояния. Естественно, встроенная система создания интерфейсов в OpenHab позволяет вам нарисовать нужные кнопки и переключатели, которые имеют биндинги к уже существующим данным в базе.

Более того, если ваше устройство поддерживается из коробки, вам даже не нужно будет делать ничего особого. Просто берёте, рисуете переключатель и привязываете состояние лампочки к этому переключателю. И вот — вы можете выключать свет с вашего телефона.

Но это дико неинтересно. Это сегодня может сделать любая лампочка из коробки.

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

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

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

Открываем openhab.cfg и создаём биндинг:

udp:port=4115

udp:buffersize=110

udp:itemsharedconnections=true

udp:bindingsharedconnections=true

udp:directionssharedconnections=false

udp:addressmask=false

udp:preamble=

udp:postamble=/r/n

udp:blocking=false

udp:updatewithresponse=false

udp:refreshinterval=250

udp:charset=UTF-8


После этого описываем устройство:

String Relay_InputString "Relay Input String [%s]" {udp="<[device_ip:source_port:’REGEX((.*))’]"}

String Relay_decString "decoded Input String [%s]"

И добавляем обработчик события:

rule:

`import org.openhab.core.library.types.*

rule "parse_Relay_InputString"

when

Item Relay_InputString received update

then

if (Relay_InputString.state instanceof StringType) {

var value = Relay_InputString.state as StringType

var valueLength = value.toString.length() as Integer

val byte[] bytes = value.toString.getBytes("UTF-8")

postUpdate(Relay_decString, bytes.toString())

}

end

И таким образом мы получаем данные из устройства. И попутно сидим и молимся о том, что в данном случае кодировка UTF-8 сработает (спойлер, на одном устройстве она сработала). Если кодировка не работает и на входе вы получаете мусор, то тут можно разбираться до конца времён. Но те, кто работал с Java, знают как в этом разобраться.

Для тех, кому это делать лень — можно пойти другим, намного более извращённым путём, который будет транслировать сообщения из TCP или UPD в JSON. Этот способ прост, если у вас есть много устройств, на которые надо отправлять команды, но из которых необязательно получать ответы. Берём любимый язык программирования и пишем свой сервер, который принимает команды на одном конце и выдаёт последовательности бит на другом. Это займёт больше времени, но если у вас есть большое количество китайских несговорчивых устройств, это может сэкономить некоторые телодвижения.

Я, например, решил эту проблему созданием сервера, в сердце которого лежало 60 строк на C#:

	public static class Executor

	{

    	public static Byte[] Say(string What, CommandType Type, string Address, int Port)

    	{

        	Byte[] bt = Type switch

        	{

            	CommandType.AsciiString => System.Text.Encoding.ASCII.GetBytes(What),

            	CommandType.UtfString => System.Text.Encoding.UTF8.GetBytes(What),

            	CommandType.Binary => ProcessBinary(What, 8),

            	CommandType.ByteArray => ProcessBytes(What),

            	_ => Array.Empty<byte>()

        	};

        	using TcpClient t = new TcpClient(Address, Port);

        	var s = t.GetStream();

        	s.Write(bt, 0, bt.Length);

        	return bt;

    	}

    	static Byte[] ProcessBytes(string What)

    	{

        	if (What.Length % 2 == 1) What += "0"; //If user sent us uneven byte count

        	List<Byte> ret = new(What.Length/2);

        	foreach (String ch in What.SplitInParts(2))

        	{

            	var d1 = Convert.ToByte(ch[0].ToString(), 16);

            	var d2 = Convert.ToByte(ch[1].ToString(), 16);

            	d1 *= 0x10;

            	d1 += d2;

            	ret.Add(d1);

        	}

        	return ret.ToArray();

    	}

    	static Byte[] ProcessBinary(string What, int WordLength)

    	{

        	List<Byte> ret = new(What.Length);

        	foreach (var ch in What.SplitInParts(WordLength))

        	{

            	ret.Add(Convert.ToByte(ch, 2));

        	}

        	return ret.ToArray();

    	}

	}

	static class StringExtensions

	{

    	public static IEnumerable<String> SplitInParts(this String s, Int32 partLength)

    	{

        	if (s == null)

            	throw new ArgumentNullException(nameof(s));

        	if (partLength <= 0)

            	throw new ArgumentException("Part length has to be positive.", nameof(partLength));

        	for (var i = 0; i < s.Length; i += partLength)

            	yield return s.Substring(i, Math.Min(partLength, s.Length - i));

    	}

	}


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

С такой заглушкой можно было быстро подключить кучу разношёрстных разноязычных устройств к openHab и продолжать конфигурировать систему.

Собственно говоря, тут уже можно делать что только душе угодно.

Более того, если вам удалось отхватить какое-то автоматическое реле за 100 рублей на “Алибаба” три года назад и оно всё ещё пылится без дела, то вы можете подключить это реле в OpenHab. Большинство дешёвых китайских подделок работают по каким-то только им известным бинарным или полутекстовым протоколам. При помощи Jyton вы сможете подключиться к несчастному реле руками через сеть и написать функции, необходимые для включения и выключения этого реле. После чего эти функции можно смело импортировать в сам OpenHab и использовать для построения своего дома.

При всём при этом, как вы видите, входной порог достаточно низок. Для того чтобы начать играться с этими системами автоматизации, вам не нужны никакие подписки. Все open-source. Wi-Fi реле можно найти меньше чем за 1000 рублей.

Для успешной работы с системами вам нужно будет выучить либо питон, либо визуальный Node.js. Если вы будете серьёзно программировать устройства, то вам потребуется понимание протоколов передачи данных, таких как MQTT. Но всё это необходимо, если вы будете серьёзно экономить на устройствах. Если же вы пойдёте путём покупки брендового оборудования, то можно обойтись программированием по методу щёлканья мышкой.

Но какой же умный дом, без того, чтобы можно было зайти и сказать: “Милая, я вернулся!”, ожидая, что ваша теперь уже напичканная электроникой квартира ответит что-то в стиле: “Сию секунду делаю кофе!”

Не стоит думать, что Алекса, Сири, Алиса и Кортана единственные на рынке (и Гугл, у них тоже что-то есть, но оно абсолютно безликое).

Один из самых больших проектов на github с открытым кодом голосового помощника называется Leon. Система сделана французом, и этот проект собрал 5.4 тысячи звёзд на платформе. Расширяемый и переписываемый помощник, который можно подключить к вашему умному дому.

После, у нас есть JARVIS из Железного Человека. Он зиждется в этом репозитории. github.com/sukeesh/Jarvis. По умолчанию этот помощник умеет работать с базовыми действиями из командной строки. После небольшой конфигурации ему можно включить голос, и писать скрипты для обработки более сложных команд.

Далее можно будет подключить SAPI модуль для обработки вашего голоса и можно запускать скрипты, которые будут дёргать ваши команды через API в OpenHab. Это позволит вам создавать вашу собственную Сири в пределах отдельно взятой сети.

Оба вышеописанных проекта написаны по лицензии MIT.

Чуть более популярная чем Jarvis, но уступающая Леону — система Mycroft. Лицензия в данном случае — Apache, и сама компания заточена на продажу собственных гаджетов в виде умных колонок и дисплеев. Хотя система и запускается в докере, но она очень просится в интернет, особенно если вы прикупите себе Mycroft гаджетов.

Существуют и другие, менее успешные open-source системы распознавания голоса. Их можно нагуглить, но они более узко специализированы и их удобнее использовать как API для ваших приложений, нежели как самостоятельные проекты.
Предупреждаю только вот о чём:

Устанавливать систему распознавания голоса надо на более продвинутое железо. Тут одна малинка не прокатит. Для того чтобы хостить собственную модель для распознавания речи, вам потребуется что-то, как минимум, с восемью свободными гигами оперативки. И желательно с приличным процессором, особенно если вы захотите как следует натаскать её на ваш голос. Так что внезапно простая затея с умным домом превращается в настройку сервера в стойке и перерастает в многолетний проект. Так что будьте осторожны.
Ну вот и всё.

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

Более того, вы сможете использовать ваше оборудование в связке с NodeRed для того, чтобы обучить ваше чадо программированию на примере физически реальных вещей. Обычно это вызывает массу интереса и вовлечённость.

Мир open-source избушки на курьих ножках достаточно прост и доступен. Дерзайте.


НЛО прилетело и оставило здесь промокоды для читателей нашего блога:

15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

20% на выделенные серверы AMD Ryzen и Intel Core HABRFIRSTDEDIC.

Доступно до 31 декабря 2021 г.
Теги:
Хабы:
Всего голосов 17: ↑17 и ↓0 +17
Просмотры 9.7K
Комментарии Комментарии 11

Информация

Дата основания
Местоположение
Россия
Сайт
firstvds.ru
Численность
51–100 человек
Дата регистрации
Представитель
FirstJohn