В этой статье пойдет речь о организации автоматического установления видео и аудио связи используя систему домашней автоматизации «Умный дом» MajorDoMo, проект Zigbee2mqtt и SIP телефонию на базе SIP сервера FreeSWITCH.

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

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

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

Немного о постановке задачи:


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

Есть два абонента:

  1. абонент А (номер 1000) — находится в пределах своей локальной сети и требует организации связи;
  2. абонент Б (номер 1019) — может находиться как в локальной сети, так и вне её.

Главная функция системы — автоматическое установление видео или аудио соединения после нажатия беспроводной кнопки абонентом А. Со стороны абонента А используется устройство терминал с видеокамерой (смартфон, планшет, ПК). При необходимости, возможность подключения громкой связи не помешает.

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

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

Решение сделано и проверено на одноплатном компьютере Raspberry Pi 3B с установленной системой домашней автоматизации MajorDoMo, SIP сервером FreeSWITCH и использованием zigbee2mqtt (в качестве координатора я использую для тестов старенький USB Zigbee стик CC2501).

Нам понадобится одноплатный или ПК компьютер (можно не самой топовой конфигурации), под операционной системой Debian, я б рекомендовал 11 или 12, USB-Zigbee стик предварительно прошитый для использования сервиса zigbee2mqtt и сама zigbee кнопка, я использовал Xiaomi WXKG01LM.

Установка и настройка SIP сервера FreeSWITCH


Первое действие после установки Операционной системы: устанавливаем и производим первоначальную настройку SIP сервера FreeSWITCH.

Подробно я описывал в публикации про «Умный Дом» и IVR меню .

Вкратце, регистрируемся на сайте разработчика signaware, получаем токен, устанавливаем из репозитория, немного правим некоторые файлы конфигурации:
Ссылка на официальную документацию по установке FreeSWITCH на Raspberry Pi
Все действия выполняются от sudo.

Файл подключаемых модулей:

sudo nano /etc/freeswitch/autoload_configs/modules.conf.xml

Изменения в файле modules.conf.xml
<!-- XML Interfaces -->
<load module="mod_xml_rpc"/>  
<!-- Say -->
<!--    <load module="mod_say_en"/> -->
<load module="mod_say_ru"/>


Настройка модуля xml_rpc.conf, задается порт, пользователь, пароль. Я изменил только порт т.к. порт по умолчанию 8080 бывает часто занят, например службой zigbee2mqtt, имя пользователя и пароль – оставил по умолчанию,

sudo nano /etc/freeswitch/autoload_configs/xml_rpc.conf.xml

Изменения в файле xml_rpc.conf.xml
configuration name=«xml_rpc.conf» description=«XML RPC»>
  <settings>
    <param name="http-port" value="9090"/>
    <param name="auth-realm" value="freeswitch"/>
    <param name="auth-user" value="freeswitch"/>
    <param name="auth-pass" value="works"/>
  </settings>
</configuration>


Изменим файл с глобальными переменными:

sudo nano /etc/freeswitch/vars.xml

Изменения в файле vars.xml
<X-PRE-PROCESS cmd="set" data="default_password=1111"/>
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/ru/RU/vika"/>
<X-PRE-PROCESS cmd="set" data="use_profile=internal"/>
<X-PRE-PROCESS cmd="set" data="default_areacode=375"/>
<X-PRE-PROCESS cmd="set" data="default_country=BY"/>


В файлах внутреннего и внешнего SIP профиля устанавливаем функцию auto-nat": FreeSWITCH будет использовать uPNP или NAT-PMP, чтобы найти нужный публичный IP-адрес


sudo nano /etc/freeswitch/sip_profiles/internal.xml


sudo nano /etc/freeswitch/sip_profiles/external.xml

Изменения в файлах профилей internal.xml и external.xml

   <param name="ext-rtp-ip" value="auto-nat"/>
    <param name="ext-sip-ip" value="auto-nat"/>


Также исправим расположение директории с голосовыми файлами


sudo nano /etc/freeswitch/lang/ru/ru.xml

Изменения в файле ru.xml
<language name="ru" sound-prefix="$${sounds_dir}/ru/RU/vika" tts-engine="cepstral" tts-voice="elena">


После правки файлов конфигураций и перезагрузки FreeSWITCH, наш SIP сервер готов для использования в домашней сети.

Протестируем его и возможность организации видеозвонков. По умолчанию у нас есть 20 абонентов с нумерацией 1000-1019. Внутренний номер абонента А – 1000.
Для тестирования я использовал два варианта:

Первый вариант: используется два смартфона как на стороне абонента А, так и у абонента Б. На обоих смартфонах установлено приложение SIP клиент для Android Linphone.

Второй вариант: на стороне абонента А ПК (ноутбук) под ОС Windows 10/11 с установленным SIP клиентом MicroSIP (также использовал десктопный клиент Linphone, но мне он не очень понравился). У второго абонента – Linphone на смартфоне. Возможно использования ПК в качестве терминала, вполне подходящий рабочий вариант, для первоначальной цели – обеспечение связи и контроля, т.к. экран побольше, можно подключить внешнюю USB камеру и гибко регулировать разные настройки: зону охвата видео, качество видео, настройки звука и микрофона и прочее).

Настройка SIP клиентов


Замечу, самое сложное и неоднозначное в решении, оказалось настройка именно SIP клиентов. Из всех протестированных мною приложений под Android, только Linphone удовлетворял моим требованиям к решению: бесплатная ПО, поддержка видео, возможность использования видео как звонка по умолчанию и функция автоответа.

Под Windows мне более подошел MicroSIP, Linphone в качестве терминала на Windows мне не очень понравился.

Настройка SIP клиента Linphone на Android:





Запускаем помощник, выбираем использовать SIP аккаунт.

Вводим свой номер (из диапазона 1000-1019), пароль (при настройке SIP сервера установили пароль по умолчанию для всех аккаунтов 1111, домен – адрес SIP сервера и вид транспорта — UDP.
Создание и настройки SIP аккаунта в приложении MicroSIP.





В SIP клиенте на стороне Абонента А включён приём видео и автоответ с небольшой задержкой (без задержки передача видео могла и не начаться, соединение устанавливается голос и видео отсутствует, с задержкой таких проблем не было).

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

Возможность внешнего управления (набора номера)


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

Проведя тестовые наборы, как простого звонка, так и видео. Всё должно работать и соединяться. Но цель – не просто в установке соединения, а управление без прямого физического воздействия на SIP телефон абонента А.

Наберём в адресной строке браузера следующий адрес (подставив свой IP адрес в своей локальной сети, экранируя служебные символы, в том числе и символ пробела — %20):


http:// freeswitch:works@192.168.1.115:9090/webapi/originate?user/1000%201011%20XML%20default

Или же эта же команда для консоли Linux:

curl "http://freeswitch:works@192.168.1.115:9090/webapi/originate?user/1000%201019%20XML%20default"

Получаем следующее: SIP сервер инициирует звонок первоначально на номер 1000 (Абонент А), SIP клиент настроен на передачу видео и автоответ. Следующий этап после поднятия трубки – звонок идёт на второе плечо (абонент Б с номером 1019), после ответа пользователя – устанавливается соединение.

Установка и настройка MajorDoMo и сервиса zigbee2mqtt


Самый простой и быстрой способ установки на linux устройства – установка с помощью скрипта от автора MajodDoMo, подробно я описывал в публикации Просто о сложном. MajorDoMo и контроль входного замка. Начало, за некоторое время добавились некоторые небольшие функции.
Пошагово, получается так: устанавливаем с помощью скрипта как систему MajorDoMo, так и, указав в опциях системный сервис zigbee2mqtt. После установки, подключаем zigbee стик, определяем на каком порту определился и при необходимости корректируем файл конфигурации zigbee2mqtt.

sudo nano /opt/zigbee2mqtt/data/configuration.yaml   

В веб-интерфейсе zigbee2mqtt (или в файле конфигурации), доступном по адресу нашего сервера c указанием порта 8080, включаем разрешение на подключение устройств. Добавляем в систему z2m устройство – беспроводную кнопку, запустив на устройстве процесс сопряжения.
Первоначальный вид интерфейса zigbee2mqtt после установки:



Вид сервиса после добавления устройства:



Настраиваем модуль системы домашней автоматизации ZigbeeDev примеры скриншота настроек и окна модуля с устройством zigbee).



Если всё правильно сделано, в системе домашней автоматизации увидим:



Создаем простое устройство, можно из Панель Управления – Простые Устройства – Добавить, можно прямо из модуля zigbeeDev:



В типе устройства указываем Клавиша, означает – запуск действия (в отличии от выключателя) и прописываем строку с командой на выполнение вызова. Эта кнопка имеет несколько вариантов нажатия: простое, двойное удержание и т.д. Используем параметр action – при любом действии будет выполняться запрограммированная команда.



В настройке Простого Устройства во вкладке Действия – Метод Logic Achion вводим свой код команды. Для системы MajorDoMo команда будет выглядеть так:

GetURL("http://freeswitch:works@192.168.1.115:9090/webapi/originate?user/1000%201019%20XML%20default")

Сохраняем и проверяем. При любом нажатии кнопки (простом, двойном, удерживание и т.д.) у нас идёт вызов с номера 1000 на телефон абонента Б. При обратном звонке – срабатывает функция автоответа на абонента А (в этом случае установка соединения не задействует функции сервера Умного Дома).

Подключение к внешнему миру


Для тестов, я использовал, уже ушедшего с региона РФ и РБ SIP провайдера Zadarma. Связь и старые аккаунты – работают. Через VPN или другими средствами, изменив свою локацию, можно и сейчас зарегистрироваться и выполнять бесплатные вызовы в сети оператора, но использование платных функций (звонки на другие сети, ВАТС и т.д.) затруднительно.
К сожалению, с подключением к официально работающим SIP провайдером у меня возникли некоторые организационные затруднения, впрочем, которые при желании вполне можно решить. Отмечу пару понравившихся с первого взгляда операторов: Novofon, Sipnet. Рекомендую всё таки компании легально оказывающие услуги на вашей территории.

Подключения к внешнему миру понадобится или как минимум 2 аккаунта одного SIP оператора или ВАТС (виртуальная АТС) с несколькими номерами.

На примере Zadarma рассмотрим подключение с двумя аккаунтам, один будет использоваться для SIP сервера (абонента А) в качестве внешней линии, второй для абонента Б на мобильном устройстве.

Создаем файл /etc/freeswitch/sip_profiles/external/sipoperator.xml (данные номера абонента А и адреса указываем полученные при регистрации/оформлении услуги).

sudo -u freeswitch nano /etc/freeswitch/sip_profiles/external/sipoperator.xml

Содержимое файла профиля

<include>
    <gateway name="sipoperator">
        <param name="username" value="AbonentA"/>
        <param name="password" value="Password"/>
        <param name="realm" value="sip.operator.com"/>
        <param name="from-user" value="AbonentA"/>
        <param name="from-domain" value=" sip.operator.com "/>
        <param name="proxy" value=" sip.operator.com "/>
        <param name="expire-seconds" value="300"/>
        <param name="register" value="true"/>
        <param name="register-transport" value="udp"/>
        <param name="context" value=" sipoperator"/>
    </gateway>
</include>


Создаём файл с настройками диалплана /etc/freeswitch/dialplan/sipoperator.xml (все звонки с номера А поступают на внутренний номер 1000, все шестизначные номера отправляются в сторону sip оператора)

sudo -u freeswitch nano /etc/freeswitch/dialplan/sipoperator.xml

Содержимое файла диалплана

<?xml version="1.0" encoding="UTF-8"?>
<include>
    <context name=" sipoperator ">
        <extension name="unloop">
            <condition field="$${unroll_loops}" expression="^true$" />
            <condition field="${sip_looped_call}" expression="^true$">
                <action application="deflect" data="${destination_number}" />
            </condition>
        </extension>
        <extension name="in- sipoperator ">
            <condition field="destination_number" expression="^( AbonentA)$">
                <action application="bridge" data="user/1000@$${domain}"/>
                <action application="hangup"/>
            </condition>
        </extension>
        <extension name="out- AbonentA">
            <condition field="destination_number" expression=" ^(\d{6})$">
                <action application="bridge" data="sofia/gateway/ sipoperator/$1"/>
                <action application="hangup"/>
            </condition>
        </extension>
    </context>
</include>


Создаем в Freeswitch внутренний номер 1000 к которому будет подключаться софтфон абонента А для приема входящих и совершения исходящих звонков. Корректируем файл /etc/freeswitch/directory/default/1000.xml

sudo nano /etc/freeswitch/directory/default/1000.xml
‎‎
Содержимое файла абонента 1000 (А)

<include>
    <user id="1000">
        <params>
            <param name="password" value="$${default_password}"/>
            <param name="vm-password" value="1000"/>
        </params>
        <variables>
            <variable name="toll_allow" value="domestic,international,local"/>
            <variable name="accountcode" value="1000"/>
            <variable name="user_context" value="sipoperator"/>
            <variable name="effective_caller_id_name" value="Extension 1000"/>
            <variable name="effective_caller_id_number" value="1000"/>
            <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
            <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
            <variable name="callgroup" value="techsupport"/>
        </variables>
    </user>
</include>


‎Перезапускаем в командной строке терминала сервис SIP сервера.

sudo  systemctl restart freeswitch.service

Настраиваем свой SIP клиент на работу с сетью оператора, в приложении Linphone возможно одновременное использование нескольких аккаунтов.

Команда для системы автоматизации при подключении к внешней сети будет иметь следующий вид (ХХХХХХ — номер абонента Б):

GetURL("http://freeswitch:works@192.168.1.115:9090/webapi/originate?user/1000%20ХХХХХХ%20XML%20public")

Проверяем, всё должно заработать.

Отмечу, имеется возможность некорректной работы установки звонков, из-за использования в сети провайдеров передачи данных технологии NAT. Проявляться может в одностороннем соединении, здесь уже лучше обращаться в тех поддержку SIP оператора или провайдера и использовать в приложениях, настройках SIP сервера FreeSWITCH, адреса STUN/TURN серверов.
Проверил на 3 разных сетях (два с симметричным NAT, у провайдера передачи данных и оператора мобильной сети, одна сеть с одинарным NAT) и только на одной возникла проблема. Решение было довольно простое – отключил в маршрутизаторе Huawei функцию SIP ALG.

Дополнение в качестве заключения


Ну а дальше систему можно усовершенствовать довольно много: можно прикрутить голосовое управление (например Алисой и умной колонкой), можно используя функции originate осуществлять вызов на несколько терминалов (отправлять в конференцию), производить запись звонков или на сторонах клиентов или на самом SIP сервере, оптимизировать работу как SIP сервера, так и системы домашней автоматизации и т.д.

Второе дополнение


Понимаю, что у некоторых пользователей, может вызвать затруднение использование Linux и серверного ПО, для отладки и тестирования возможна установка основных компонентов и на Windows системы: сервер SIP телефонии FreeSWITCH, сервис Zigbee2mqtt так и системы автоматизации MajorDoMo (её я б рекомендовал бы в качестве тестовой устанавливать с пакетом XAMPP) имеют возможность установки на Windows. Хотя навряд ли, без хорошего знания используемой операционной системы, это решение будет стабильным, но в качестве тестов или необходимости быстрого развёртывания решения вполне может иметь место и кому-то будет легче и быстрее пойти таким путём.

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


  1. Dr_Faksov
    24.12.2024 22:39

    Я не увидел самого главного - как физически реализована кнопка? Зачем писать заголовок про кнопку, ели вся статья о том, что будет после её нажатия! А о том как её нажать - ни слова.

    А надо учесть, что человек после инсульта может быть полностью неподвижен. Если у человека не работают руки, то вся эта статья - ни о чём.


    1. udvnl Автор
      24.12.2024 22:39

      Вы в чём то правы, в статье я не акцентировал внимание и не занимал место, исполнением кнопки, только указал её модель: Xiaomi WXKG01LM (довольно распространённая в моем регионе, можно зайти практически в любой магазин электроники или представителю Xiaomi и пощупать её).
      Более того, кнопка может быть практически любая, работающая по протоколу zigbee.
      Т.к. она беспроводная, то можно установить в любом месте, а не за головой, как сделано во многих больницах.

      А надо учесть, что человек после инсульта может быть полностью неподвижен. Если у человека не работают руки, то вся эта статья - ни о чём.

      В послесловии я указал дополнительные возможности в т.ч. и голосовое управление (например Я колонками), которое можно довольно легко реализовать.
      Если человек неподвижен, то можно тогда использовать уже второй вариант пользования, звонить самому на УД для трансляции видеоизображения. Ну и можно попробовать использовать другие датчики по протоколу zigbee (например датчик вибрации в качестве датчика падения).


  1. udvnl Автор
    24.12.2024 22:39

    Если требуется использование какой либо проводной физической кнопки (стандартные 2 провода/контакта), то я б, скорее всего использовал, датчик открытия/закрытия двери (работающий по протоколу zigbee), подпаявшись к контактам геркона. Плюс в отличии от релейного модуля - небольшой закрытый корпус и отсутствие проводов питания.