Умный дом с голосовым ассистентом на минималках

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

Разработка шла с переменной скоростью в течении лет 5. Совсем не сразу взялся за летопись, поэтому прошу прощения, если что-то будет некорректно ;)

В результате имеем масштабируемое решение, которое можно использовать в любом месте (квартира, дом или еще что):

  • Raspberry PI4 + POE

  • дисплей для отображения статуса

  • Голосовой ассистент работающий как онлайн, так оффлайн с поддержкой chatGPT по сложным вопросам

  • датчики:

  • устройства управления:

  • web сервер для отображения статусов, графиков

  • telegram бот для отображения графиков, статуса и управления всем

Глава 1. Начало

Из за того, что не поливал цветы дома они часто высыхали. Для того, чтобы это исправить был закуплен в 2018 raspberry PI3 и решил было организовать автоматический полив с размахом и не ограничиваясь бюджетом с учетом того, что это должно было вырасти в центр умного дома в дальнейшем. Реализовал простой полив, наблюдение за растениями по камере и заодно приделал датчик температуры (DHT11), и управление вентилятором чтобы можно было усиливать обогрев комнаты если в ней холодно продувом через батарею теплого воздуха.

Запас воды хранился в 5-ти литровой бадейке купленной в Ашане и выкачивался по шлангу с помощью моторчика в растение.

5V моторчик, время жизни 6-8 месяцев

5V моторчик, время жизни 6–8 месяцев

Вначале пробовал самые простые и дешевые моторчики, но спустя 6–12 месяцев из за того, что вода жесткая они выходили из строя

12V моторчик, время жизни более 1-2 года, пока не сломался

12V моторчик, время жизни более 1–2 года, пока не сломался

в результате перешел на 12V, последние 2 года с ним проблем нет, при этом он достаточно мощный, чтобы поднимать воду на значительную высоту.

Экономия на корпусе - просто банка ;)

Экономия на корпусе — просто банка ;)

Вначале для управления периферией использовал обычные реле, но их щелканье, особенно когда в комнате тихо не особенно комфортно. Поэтому решил не экономить и для управления разно-вольтовой периферией купить твердотельное реле. Управлять через GPIO с raspberry периферией напрямую утопия конечно, особенно если расстояние от борды 1–2 метра.

График температуры и влажности, датчик влажности барахлит время от времени

График температуры и влажности, датчик влажности барахлит время от времени

Аппетит как известно приходит во время еды, раз есть железка, то можно ее улучшать ! (самое главное, чтобы было время ;))
Логично приделать базу данных, чтобы хранить информацию о поливах и отслеживать что и когда произошло, а раз копится информация о температуре и влажности, то ее хорошо бы отображать визуально через web интерфейс (прикрутил flask для этого).

Первая версия бота

Первая версия бота

Дальше возник вопрос, что делать например если ты на работе, а есть желание посмотреть, что происходит дома, включить или выключить устройства. Как решение могло выглядеть Android приложение через прокси имеющее доступ к внутренней сети (белого айпишника не было), но более простым и быстрым решением выглядел telegram бот.

Глава 2. Датчики

Интерфейс telegram бота

Интерфейс telegram бота


Следующими интересными датчиками стали датчик CO2 (MH-Z19) и уровня частиц (PMS7003).

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

Пример меню бота с предупреждением

Пример меню бота с предупреждением

И естественно надо предупреждать, если забываешь открыть окно или что-то произошло нехорошее (тут уже напоминания через почту и бота), например если температура выше 40 градусов в комнате.

Плата с датчиками

Плата с датчиками

Так как датчиков стало много, то стало интересно их вынести на внешнюю плату и опрашивать.

Для большей стабильности по питанию добавил конденсатор, иначе при длине кабеля в 1–2 метра между платой и raspberry были проблемы и сенсоры DHT11/22, CO2 работали нестабильно.

Также теперь на один UART стало 2 устройства, значит нужно приделать переключение между ними, что реализовал с помощью cd74hc4052 и по GPIO можно переключать между устройствами итого получается можно подключить уже не одно, а четыре устройства на UART.

Raspberry PI4 + RJ45 подключение датчиков + POE адаптерНа этом фото POE адаптер без 12 В, в дальнейшем был заменен на адаптер выдающий также 12В.

Raspberry PI4 + RJ45 подключение датчиков + POE адаптер
На этом фото POE адаптер без 12 В, в дальнейшем был заменен на адаптер выдающий также 12В.

Со стороны Raspberry — RJ45 разьем на GPIO. RJ45, значит можно использовать обычный сетевой кабель для подключения, что довольно удобно.
Изначально был Raspberry PI3, и все висело на UART0, для этого пришлось его отключить от внутренних нужд raspberry через :

enable_uart=1
dtoverlay=pi3-miniuart-bt
core_freq=250

Из payback — устройство перестало перезагружаться софтверно, приходилось перевключать питание, что не очень удобно.

С переходом на Raspberry PI4 появилась возможность перейти на uart3, что более комфортно и проблемы с софтверной перезагрузкой ушли. Также PI4 значительно мощнее 3 и у него больше памяти, что положительно сказалось при работе с TTS и STT, но об этом позже.

Глава 3. Дисплей

Дисплей с минимальной информацией и графиками

Дисплей с минимальной информацией и графиками

Для любого устройства всегда интересно графическое отображение информации, так как появилась возможность использовать несколько UART устройств, то логично было подключить дисплей на UART, был выбран 3.2 inch Nextion дисплей, он позволяет настраивать template для отображения и затем передавать одиночные данные, так как картинка планировалась по большей части статичной не хотелось подключать дисплей по HDMI и гонять на него данные, также это позволяло интегрировать дисплей с платой расширения.

Глава 4. Расширение датчиков и устройств

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

  • DHT11 датчик температуры — влажности довольно не точный и был заменен на DHT22, рекомендую сразу ставить его

  • Поливать растения надо не только по расписанию, но и по влажности почвы, значит нужен датчик влажности. Датчик прожил где-то месяцев 3–6, после чего весь окислился, и от него отказался, не рекомендую.

  • Датчик присутствия воды в шланге полива

    Простой провод в шланге для обнаружения воды, как это выглядит

    Простой провод в шланге для обнаружения воды, как это выглядит

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

    Инициализация в коде

    Инициализация в коде

  • Датчик уровня воды, пробовал с aliexpress также окисляется и толку от него не много

  • Датчик освещенности — самый простой, работает до сих пор, используется, чтобы решить в какое время можно озвучивать предупреждения, а в какое лучше промолчать, так как ночь

  • Также для управления внешними устройствами 220В добавил выносную релюшку в отдельном корпусе c розеткой

  • Для того, чтобы не плодить провода и зарядки перевел питание всей системы как 5В так и 12В на POE адаптер с выходом на 5 и 12 В. Удачно он работает как на Rasbperry PI3 так и на PI4

  • IR управление, естественно как же без него, в доме как минимум 2 устройства телевизор и кондиционер использовали IR.
    Довольно много времени потратил на исследование этой темы, в процессе исследования сигналов IR пригодился DSLogic анализатор, но тема была осилена и кондиционер сдался и перешел на управление от raspberry
    В результате можно было включать кондиционер например по дороге домой и приезжать в комфортное условия.

  • WOL: так как был доступ к локальной домашней сети и управление через telegram бота, иногда надо было удаленно подключаться к заснувшим компьютерам в сети, логично и несложно было добавлено управление через бота

    Глава 5. Рефакторинг

    0fbc61a3b476e70efc2a49b8ec7c07c5.png

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

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

    Также шину данных в приложении, так как например температура могла получаться от DHT11/22, но если их не было, то грубое значение температуры можно было получить из CO2 сенсора также.

    Упорядочил работу с UART так как он был нужен во многих местах.

Глава 6. Java

9f92f94191acd0bfe8279f70a4f99430.png

В работе часто использовал Java, она казалось более стабильной чем python, так как все синтаксические ошибки видны были сразу на этапе компиляции к тому же она более подходила для сложного проекта, как мне виделось. Обновил железо на Rasbperry pi 3 B+, у него было 1 Гб оперативной памяти вместо 0.5 Гб, так как Java требовала больше памяти. Начал переписывать проект на Java, реализовал телеграм бота, часть сенсоров, но из за нехватки времени это направление остановилось, на питоне гораздо быстрее все набросать и запустить.

В итоге Java: Python 0:1;)

Глава 7. Голосовое управление

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

Потом попробовал онлайн варианты реализаций:

  • Google (speech_recognition) — вполне работает, есть дефолтный бесплатный токен, но на нем ограниченно количество запросов

  • Yandex (speechkit) — работает, но просит денег

    Естественно так как это не коммерческий продукт, платить не собирался, поэтому выбрал Google. Длительное время с ним жил, не очень комфортно, так как из-за ограничения на количество запросов, постоянно отваливалось и не мог в результате полагаться на устройство. Пока не подсказали о оффлайн библиотеке:

  • Vosk (vosk) — попробовал и о чудо все работает без интернета, без платежей на вполне приемлемом качестве и без серьезных задержек. Этот факт уже ставит разрабатываемое устройство интереснее колонок, так как оно уже не зависит от интернета. При этом эта библиотека поддерживает русский язык, в результате остановился на ней.
    Пробовал большую модель загрузить, если у Raspberry 8 Гб, она даже может заработать (правда хорошо при этом еще задействовать zram), но медленность реакции ставит крест на этом использовании, в результате остановился на малой модели.
    Из минусов стоит еще отметить, что хотя нормально распознает голос взрослого, ребенка не смогла услышать.

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

Глава 8. Голосовое воспроизведение

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

  • espeak пакет в linux — качество мягко говоря не очень

  • sphinx (pyttsx3) — также проблемы с качеством

  • Yandex (yandex_speech) — хорошее качество, но хотят денег

  • Google (gtts) — хорошее качество, хотят денег, но есть дефолтный бесплатный ключ, правда если много запросов по нему делать начинаются задержки. Также длительное время сидел на Google, пока не познакомился с Vosk, после чего начал поиски похожей библиотеки для генерации голоса, в результате нашел:

  • Silero — оффлайн, базируется на torch. К этому времени сменил hardware с Raspberry PI3 на PI4 64 bit, что позволило поставить и использовать torch без проблем.
    Warning, если ставить через wheel, то ставится torch 2.0 и с ним не работает, поэтому надо ставить 1.13:

    версии которые заработаили на raspberry PI4

    версии которые заработаили на raspberry PI4

    Но минус Silero в задержках, простая фраза генерируется 10+ секунд, в то время как Google TTS выдает результат за 1–2 секунды, что существенно. Поэтому Silero остается как fail safe вариант, если Google TTS не заработает или не будет интернета. Из минусов можно еще отнести то, что Silero не понимает например числа из коробки и для того, чтобы оно его произнесло надо сначала число преобразовать в текст, из плюсов — можно поиграться в этим процессом и открыть для себя что-то новое;)

Глава 9. Улучшение голосового управления

нормализация звука на С с использованием CPython

нормализация звука на С с использованием CPython

В принципе Jabra достаточно хорошо вычищает звук, но хотелось лучшего, для этого добавил нормализацию звука, чтобы быстрее работало, сделал через C на python, чтобы быстрее работало. Этого показалось мало, поэтому добавил еще простой шумодав noisereduce.

По итогу noisereduce помогает, удалось добавить примерно 1 метр к дальности распознавания, а если включить нормализацию то видимо идут искажения и качество падает. В результате отказался пока что от нормализации, может вернусь к этому после того, как сделаю разделение на фразы, можно будет приделать шумодав из ffmpeg также.

Заключение

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

Репозиторий проекта для ознакомления и welcome to принять участие в проекте и улучшать его: https://github.com/AMV007/raspberry_house_control

Планы

Если найду время конечно, идей pet проектов всегда много ;)

  • перевести на плату расширения на zigbee

  • добавить zigbee сенсоры и устройства управления

  • добавить поплавковый датчик уровня воды

  • датчик движения (после освоения zigbee)

  • добавить вычитание воспроизводимого из микрофона, чтобы можно было бы управлять устройством во время воспроизведения радио или музыки

  • добавить распознавание фраз, чтобы приделать шумоподавление и более эффективную нормализацию

  • добавить возможность воспроизведения с локального NAS как видео так и музыки (то чего очень не хватает в Алисе)

  • добавить для всего корпус на 3D принтере

© Habrahabr.ru