DIY кнопка вызова. Raspberry Pi, MajorDoMo, Freeswitch и Linphonec

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

Возможно с небольшими переделками, совмещение VoIP телефонии с системой домашней автоматизации. Как варианты использования – SIP дверной звонок, интерком, система голосовой связи (клиент-персонал, директор-секретарь) и т.д.


Всё решение делается на бесплатном и открытом программном обеспечении: операционная система – Raspbian Stretch (Debian 9), Система домашней автоматизации – MajorDoMo, VoIP сервер – Freeswitch, программный клиент IP-телефонии с возможностью работы в терминальном режиме Linphonec.

В этой части, под катом, в основном и пойдет речь про установку консольного SIP клиента Linphonec.

Нам понадобится:

  1. Raspberry Pi — одноплатный компьютер (у меня модель Raspberry Pi 3B)
  2. Micro SD карта памяти не менее 16 Гб, USB зарядное устройство, корпус.
  3. USB звуковая карта (использована одна из самых дешевых, Gembird), микрофон, динамик (наушники).
  4. Кнопка и пару перемычек BBJ для контактов GPIO.

1. Первый шаг — Установка образа MajorDoMo для RPI
На данный момент актуальная версия образа для Raspberry Pi — v. 3.40. По ссылке небольшое описание образов MajorDoMo и изменений:

Базовые образы MajorDoMo для Raspberry Pi

После установки и при загрузке системы, подключив динамики к 3,5 разъёму – услышим системные сообщения и IP адрес Raspberry.

По умолчанию имя пользователя: pi пароль: raspberry.

2. Устанавливаем FREESWITCH,
Установка VoIP сервера FRESWITCH для Raspberry

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

Установка RPi-Monitor


Установим небольшую, но полезную утилиту RPI монитор, которая показывает ресурсы нашего Raspberry PI.

RPi-Monitor это основанное на веб, программное обеспечение для контроля за платами Raspberry Pi. Данный инструмент может быть полезен, чтобы контролировать использование дискового пространства, нагрузку на процессор, память и сетевой трафик, температуру. RPI-Monitor довольно прост в установке, и наглядно показывает информацию о системе.

Первым делом приведу ссылку на первоисточник:
RPi-Monitor .

Устанавливаем публичный ключ RPi-Monitor и добавляем его в доверенные репозитории:

sudo apt-get install dirmngr
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2C0D3C0F
sudo wget http://goo.gl/vewCLL -O /etc/apt/sources.list.d/rpimonitor.list

Далее обновляем систему и устанавливаем сам RPI монитор:

sudo apt-get update
sudo apt-get install rpimonitor

Открываем в браузере IP своего комп с указанием порта :8888, на котором работает монитор и видим состояние RPI.



Установка USB аудиокарты и настройка звука в ОС Raspberry Pi


К сожалению наш мини компьютер Raspberry не имеет своего своего встроенного микрофона и входа для него. Поэтому для подключения микрофона придется использовать внешнюю USB звуковую карту. Подключаем карту в порт USB Raspberry, и выполняем команду (которая показывает устройства звука в системе):

cat /proc/asound/cards

Видим ответ с двумя картами, bcm2835 – встроенная, внешняя определилась как USB Audio Device:

0 [ALSA ]: bcm2835_alsa — bcm2835 ALSA
bcm2835 ALSA
1 [Device ]: USB-Audio — USB Audio Device
GeneralPlus USB Audio Device at usb-3f980000.usb-1.4, full speed

ОС видит нашу звуковую карту, но она ещё не прописана в системе.

Создаем файл:

sudo nano /etc/modprobe.d/alsa-base.conf 

Пишем (вставляем) следующую строку:

options snd-usb-audio index=1

Сохраняем (в редакторе Ctrl+X).

Создаем ещё один файл:

sudo nano /etc/asound.conf  

Добавляем содержимое:

содержимое файла
pcm.!default {
type plug
slave {
pcm "hw:1,0"
}
}
ctl.!default {
type hw
card 1
}


Редактируем следующий конфигурационный файл:

sudo nano /usr/share/alsa/alsa.conf 

Меняем звуковую карту по умолчанию с 0 на 1 (USB card), Очевидно, 0 по умолчанию встроенный выход звука миникомпьютера, устанавливаем в 2-х строках следующие параметры:

defaults.ctl.card 1
defaults.pcm.card 1

Изменения вступят в силу, после перезагрузки, перегружаем набрав в консоли:

sudo reboot

Подключаем в внешнюю аудиокарту микрофон и колонки (наушники). После перезагрузки запускаем утилиту настройки звука Alsamixer.

alsamixer

Видим наши устройства, которые мы определили в системе по умолчанию:



Клавишами курсора вправо-влево, выбираем необходимое устройство, вверх-вниз, регулировка, обращаем внимание на символы под выбранным устройством:

xOOx — устройство включено, xMMx – устройство отключено. Как видно на скриншоте, у меня микрофон по умолчанию в системе был выключен.
Чтоб включить/выключить устройство требуется на клавиатуре нажать М.
Выходим из alsamixer (выход ctr+C).
Проверяем звук в системе. Динамики и микрофон подключены к соответствующим выходам USB звуковой карты.

Даем команду:

arecord -D plughw:1,0 -f cd /home/pi/test_record.wav

При этой команде через микрофон записывается звуковой файл в соответствующую директорию (в нашем случае, домашнюю пользователя pi). Остановка записи Ctrl+c.

Проверяем записанный файл:

aplay  /home/pi/test_record.wav

Более качественную проверку проведём чуть позже.

Установке консольного VoIP клиента Linphonec


Программ, имеющих возможность работы в ОС без графического интерфейса не так уж и много, я остановился на пакете Linphone.

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

Ради нее и будут выполнены последующие действия.

Замечу, при установке из репозитория Raspbian устанавливается довольно старая версия 3.6.1, которая не совсем корректно не работает с звуковой системой ALSA, у меня были пропадания звука, сама программа несколько раз вылетала.

Поэтому буду использовать более актуальную версию.

Для самостоятельной сборки пакета из исходников устанавливаем дополнительные зависимости:

sudo apt-get install cmake automake autoconf libtool intltool yasm libasound2-dev libpulse-dev libv4l-dev nasm git libglew-dev

Переходим в домашнюю директорию:

cd /home/pi/

Скачиваем сам пакет Linphone, скачивание заняло минут 20.

git clone git://git.linphone.org/linphone-desktop.git --recursive

Скомпилировать и собрать пакет Linphone у меня не получилось с первого и даже не со второго раза. Поэтому приведу свой алгоритм действий.

Останавливаем практически все запущенные, но на текущий момент неиспользуемые сервисы, с помощью системы управления службами systemctl.

При сборке возникали ошибки, нашему мини ПК просто не хватает своих ресурсов. Освободим их для установки.

Остановка служб
sudo systemctl stop freeswitch.service
sudo systemctl stop majordomo.service
sudo systemctl stop avahi-daemon.socket
sudo systemctl stop avahi-daemon.service
sudo systemctl stop mosquitto.service
sudo systemctl stop mysql
sudo systemctl stop mpd.service
sudo systemctl stop mpd.socket
sudo systemctl stop homebridge.service
sudo systemctl stop nginx.service
sudo systemctl stop bluetooth.target
sudo systemctl stop bluetooth.service


На всякий случай можем сделать, временный (до перезапуска) файл подкачки, (место на жестком диске), которое операционная система использует в случае нехватки оперативной памяти.
Проверить, включен ли в нашей установке Raspbian (Debian) файл подкачки, можно набрав:

sudo swapon --show

Вывод пуст, это означает, что в системе отсутствует файла подкачки.
Добавим 1G swap и создадим файл:

sudo fallocate -l 1G /swapfile

Только пользователь root может читать и писать в файл подкачки, поэтому устанавливаем правильные разрешения:

sudo chmod 600 /swapfile

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

sudo mkswap /swapfile
sudo swapon /swapfile

Переходим в созданную директорию при скачивании пакета:

cd linphone-desktop

Подготавливаем к установке версию без графического интерфейса:

sudo ./prepare.py no-ui -DENABLE_OPENH264=ON -DENABLE_WEBRTC_AEC=OFF -DENABLE_UNIT_TESTS=OFF -DENABLE_MKV=OFF -DENABLE_FFMPEG=ON -DENABLE_CXX_WRAPPER=OFF -DENABLE_NON_FREE_CODECS=ON -DENABLE_VCARD=OFF -DENABLE_BV16=OFF -DENABLE_V4L=OFF

Выполняем сборку используя атрибут –j4 (т.е. выполняет сборку в 4 потока одновременно.

sudo make -j4

Можем при установке, посмотреть в RPI-Monitor состояние нашего компьютера:



Время сборки у меня составило около 30-40 минут.

Собранные файлы программ появились в директории OUTPUT/no-ui/bin. Для запуска программы перейдём в неё:

cd OUTPUT/no-ui/bin

Проверяем версию программы:

./linphonec -v

Получаем результат: version: 3.12.0
Перегружаем наш Raspberry
При перезапуске исчезает файл подкачки, восстанавливаются все запущенные сервисы прописанные в автозагрузке.

Небольшая первоначальная настройка Freeswitch.


Сервер FREESWITCHу нас устанавливается по умолчанию в директорию /usr/local/freeswitch/. В папке conf хранятся файлы конфигурации. По умолчанию устанавливается тестовая конфигурация vanilla, которая большей частью служит для ознакомления с возможностью VoIP сервера и содержит большое количество примеров, которые явно избыточны для домашнего использования. Приведем сначала к работоспособности VoIP сервера конфигурацию из коробки.

Отредактируем файл конфигурации vars.xml

sudo nano /usr/local/freeswitch/conf/vars.xml

Первым делом изменим пароль по умолчанию 1234 на другое значение, допустим 1111. Если этого не делать, то перед каждым звонком устанавливается пауза до набора номера равная 10 секундам.

По умолчанию, как писал в предыдущей статье, у нас есть 20 абонентских номеров 1001-1020. Диалплан также установлен по умолчанию.

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

Диалплан FreeSWITCH широко использует регулярные выражения. За обработку вызовов отвечает дефолтный диалплан, за направление на наши локальные номера отвечает следующая секция файла Local_Extension. Закомментируем несколько строк:

sudo nano /usr/local/freeswitch/conf/dialplan/defaults.xml

Редактирование диалплана, вставим символа комментария в эту секцию:

Редактирование диалплана номеров 1001-1019
<extension name="Local_Extension">
      <condition field="destination_number" expression="^(10[01][0-9])$">      
	<action application="export" data="dialed_extension=$1"/>                                                                                                                                                                                                                     
<!--   <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
        <action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
        <action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
        <action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>  --> 


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

Настройка и запуск терминального клиента Linphonec


Запустим Linphonec в режиме автоответа от текущего пользователя pi:

/home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonec -a

При первом запуске, Linphonec пытается создать файл базы данных и файл настроек. Однако запуск происходит с ошибками.

ошибки при запуске Linphonec
2019-08-02 18:02:58:715 mediastreamer-error-Connection to the pulseaudio server failed
2019-08-02 18:02:58:946 belle-sip-error-udp bind() failed for ::0 port 5060: Address already in use
2019-08-02 18:02:58:947 belle-sip-error-TCP bind() failed for ::0 port 5060: Address already in use
2019-08-02 18:02:59:126 liblinphone-fatal-Unable to open linphone database.
Aborted


Первоначально разберемся с последней ошибкой, открытия файла БД.

Файл БД создается в домашней директории по следующему пути: /home/pi/.local/share/linphone
Файл (или директория) в Linux считается скрытым (hidden), если его название начинается с символа точка «.». Например, «.myfile». Обычно такие файлы используются приложениями для хранения настроек, конфигураций и другой информации, которую нужно скрыть от пользователя.
Создадим директорию от текущего пользователя (pi)
mkdir /home/pi/.local
mkdir /home/pi/.local/share
mkdir /home/pi/.local/share/linphone

Запускаем программу, программа запустилась, но выдает ошибку:
Ошибка открытия порта
2019-08-07 11:29:32:780 mediastreamer-error-Connection to the pulseaudio server failed
2019-08-07 11:29:32:866 belle-sip-error-udp bind() failed for ::0 port 5060: Address already in use
2019-08-07 11:29:32:866 belle-sip-error-TCP bind() failed for ::0 port 5060: Address already in use


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

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

Вторая – порты 5060 заняты. Эти порты обычно используется SIP приложениями. Можем выйти из программы и дать команду:

sudo netstat -tulpn | grep LISTEN

Увидим, что порт 5060 использует наш сервер VoIP FREESWITCH. Что ж, будем использовать свободные порты.

Заходим обратно в программу linphonec. И проводим небольшую настройку.

Первым делом меняем порт для Линфона, затем указываем регистрацию к серверу VoIP, проверяем статус регистрации и смотрим список звуковых карт, используемую карту и настраиваем на внешнюю USB (с индексом в программе Linphone – 2):

ports sip 5062
register sip:1001@192.168.15.13 192.168.15.13 1111 
linphonec> help register
status register
soundcard list
soundcard show
soundcard use 2
soundcard show



В команде регистрации используем следующий формат: идентификатор Sip пользователя – по умолчанию у нас 20 абонентов с номерами 1001-1019. Эти номера и есть логины абонентов логин абонента@[Доменное имя] – доменное имя – IP адрес нашего Raspberry. Sip proxy – совпадает с IP адресом RPI, и в конце – пароль пользователя, который мы недавно установили 1111.

Выходим из программы (Ctrl+x), не всегда на лету применяются настройки. После выхода в домашней директории /home/pi появился файл настройки консольного клиента: .linphonerc.
Можем уже вносить изменения, редактируя конфигурационный файл SIP клиента.
По новой запускаем консольного SIP клиента.
Параллельно с текущей SSH сессией, открываем новую, входим в систему, используя свой логин и пароль.
Запускаем alsamixer. В одной сессии у нас Linphonec, в второй утилита настройки звука.
Делаем установку вызова с SIP клиента на смартфоне или пк (как описано в статье про установку FREESWITCH), изменив дефолнтный пароль на свой и набрав номер, в нашем случае 1001. Можем зайти в портал freswitch по адресу IP_Raspberry:8080, просмотреть регистрацию абонентов, состояние звонка и т.д.



С помощью alsamixer настраиваем звук. Изменения звука применяются на лету, без выхода из программ.

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

Поэтому раз не удалось убрать одним способом, устраним другим.
Закрываем Linphonec, редактируем файл конфигурации:

sudo nano /home/pi/.linphonerc

В секции звука приводим три последние строчки к такому виду:

Секция звука Linphonerc
[sound]
remote_ring=/home/pi/linphone-desktop/OUTPUT/no-ui/share/sounds/linphone/ringback.wav
playback_gain_db=0.000000
mic_gain_db=0.000000
ringer_dev_id=ALSA: bcm2835 ALSA
playback_dev_id=ALSA: bcm2835 ALSA
capture_dev_id=ALSA: USB Audio Device


Таким способом мы заставили устройство звонка и устройство вывода звука работать на встроенном 3,5 jack малинки, а устройство записи — микрофон работать через внешнюю звуковую карту — эхо исчезло.

Переключаем динамики в родной разъём малинки.

Учитываем следующий момент: при загрузке и в некоторых случаях, система умного дома воспроизводит через этот аудиовыход свои системные сообщения.

Отключим их. Переходим по IP_Rasberry на главную страницу, открыв систему домашней автоматизации MajorDoMo.

Входим в панель управления – объект- Computer (раскрываем устройства) – ThisComputer на вкладку Свойства и ставим значения:

 ThisComputer.minMsgLevel 100   ThisComputer.volumeLevel 0



Добавляем запись в cron (программа-демон, предназначенная для выполнения заданий в определенное время, или через определенные промежутки времени. Для редактирования заданий используется утилита crontab):

crontab –e

Замечу делаем это из под пользователя pi.

Вставляем в самом конце строку:

@reboot /home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonec –a

Эта строка запускает при перезагрузке, включении компьютера, программу Linphonec в режиме автоответа.
Обратно вернемся к MajorDoMo:
Перейдем на главную страницу, в раздел сервис:
В меню этого раздела созданы для перезагрузки (выключении) компьютера кнопки.
Дело в том, что для экономии ресурсов SD карты памяти, запись изменений в систему «умного дома» производится через определенное время (15 минут). Поэтому, если нужно перегрузить малину, то лучше это делать правильно. Выполняем перезагрузку системы.



После перезагрузки, заходим на главную страницу MajorDoMo, переходим в панель управления, и как в прошлой статье делаем вызов из консоли используя следующий формат:

GetURL("http://freeswitch:works@192.168.1.103:8080/webapi/originate?user/1001%201003%20XML%20default")

После команды Linphonec автоматически снимает трубку. В динамике RPI идет проигрывание звукового файла, на второй софтфон (ПК/смартфон) поступает вызов. Подняв трубку (нажав в программе кнопку ответа) устанавливается соединение.



На этом, заканчиваю эту часть. Постараюсь, немного позже описать о самой кнопке с использованием GPIO и установку вызовов за пределами своей локальной сети.

Who's online

There are currently 1 user and 1 guest online.