Разработка систем связи
Разработка на Raspberry Pi
Умный дом
DIY или Сделай сам
12 декабря 2019

DIY кнопка вызова часть 2. Видеофон из Raspberry Pi

Tutorial
В этой части делаем из Raspberry Pi VoIP устройство для осуществления видео вызовов по SIP протоколу.

Первоначальная задача осталась прежней — осуществление вызова по внешнему воздействию (нажатию кнопки). Но немного изменилась реализация идеи. Как и в предыдущей части, воспользуемся терминальным SIP клиентом Linphonec, но в целях упрощения настройки, я решил воспользоваться VoIP провайдером Zadarma.com с бесплатными внутрисетевыми звонками, в том числе c поддержкой видео. Для видео звонков я использовал бюджетную USB камеру.

Подробности, а также пошаговая инструкция под катом.

Первая часть
Системы развернута на базовом образе для RPI v3_40_int из коробки без установки чего либо дополнительного.

Ссылка базовые образы MajorDoMo для Raspberry

Вебкамера, которую я использовал — бюджетная (около 7 уе, в Минске) — Ritmix RVC-015M. Имеет возможность ручной настройки фокуса.

В процессе тестирования и для написания поста, я решил отказаться от использования своего VoIP сервера (Fresswitch). Установка своего VoIP сервера усложняет процесс настройки, но дает более гибкие возможности.

Для примера, воспользуемся представленным на Хабре VoIP оператором Zadarma.

Для осуществления звонков нам требуется две учетные записи на SIP сервере. Под одной будет работать Raspberry Pi и консольный клиент, вторая для смартфона (или же ПК). Процесс регистрации интуитивно понятен, и не нуждается в описании.

Немного кратко повторю по установке и настройке пакета Linphone, более подробные сведения в первой части.

Установка и сборка Linphone


Подготовка к установке:


Останавливаем запущенные, но неиспользуемые сервисы:

Остановка служб
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


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

Поочередные команды: проверка, включен ли в нашей установке Raspbian (Debian) файл подкачки, если вывод пуст, это означает, что в системе отсутствует файла подкачки.
Добавляем 1G swap и создаем файл.

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

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

sudo swapon --show
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Установка консольного SIP клиента Linphonec и утилиты управления Linphonecsh


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

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

Переходим в домашнюю директорию и скачиваем сам пакет Linphone, скачивание заняло минут 20:

cd /home/pi/
git clone git://git.linphone.org/linphone-desktop.git -recursive

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

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

Сборка занимает минут 30-40.

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

cd OUTPUT/no-ui/bin
./linphonec -v 

Получаем результат: version: 3.12.0

Перегружаем наш Raspberry.

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

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


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

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

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

Как в первой части cсоздаём директорию от текущего пользователя (pi)

mkdir /home/pi/.local
mkdir /home/pi/.local/share
mkdir /home/pi/.local/share/linphone

Т.к. в нашем случае мы не используем VoIP сервер, то используется стандартный порт для IP телефонии 5060.

Произведем регистрацию одного из аккаунтов выполнив в Linphonec следующую команду:

register sip:XXXXXX@sip.zadarma.com sip.zadarma.com YYYYYYY  

формат команды можно посмотреть набрав help register.

В нашем случае XXXXXX — номер (логин) учетной записи, YYYYY — пароль, выдаваемый при регистрации. Проверим регистрацию:

status register

ответ при успешной регистрации: registered, identity=sip:XXXXX@sip.zadarma.com duration=3600

Выход из клиента осуществляется по нажатию ctrl+c или командой quit.

После выхода в домашней директории /home/pi появился файл настройки консольного клиента: .linphonerc.

Подключение WEB видеокамеры


Подключаем к Raspberry камеру.

Проверяю, включена ли моя учетная запись в группу video

cat /etc/group | grep video

Ответ: video:x:44:pi

Посмотрим определилась ли веб-камера в вашей системе:

sudo ls -l /dev/ | grep video

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

arecord -l

Ответ:

List of CAPTURE Hardware Devices
card 1: CAMERA [USB2.0 PC CAMERA], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0


Всё в порядке, микрофон тоже есть. Проверим его в алсемиксере

alsamixer

Сразу уточню, микрофон у меня по умолчанию включен, определился как основной и выкручен почти полностью, идет сильное переусиление.

Нажимаем F6 (выбор карты), выбираем USB PC Camera, дальше F4 — устройство Capture (микрофон на камере), опустим его уровень почти до нуля, курсорными клавишами вниз, заодно проверим и Capture.

"

В маркете приложений для Android устанавливаю приложение Linphone (перепробовал несколько, только у него завелась трансляция видео. На Windows все SIP клиенты, которыми я пользуюсь — работают без проблем. Так же без проблем заводится на моем SIP сервере (freeswitch, если использовать в локальной, да и не только сети, то наилучший вариант свой сервер + шлюз для звонков из своей локальной сети).

Инструкция по настройке приложения для Android Linphone приведена на сайте Zadarma.com.
Инструкция от SIP провайдера .

Производим регистрацию мобильного телефона на Zadarma, далее по желанию настраиваем опции видео, аудио и т.д.

Для тестирования запустим в RPI утилиту linphonec с функцией видео звонка и автоответа (добавив ключи -V -a):

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

и произведём вызов в терминальном клиенте набрав:

call 576935

подстановка сервера VoIP (домена) производится автоматически, хотя можно и полностью набрать SIP адрес.

В итоге получим:


(более менее хорошее качество для этой камеры на расстоянии до метров 2-3-ех от объектива).

Можем проверить режим автоответа, набрав на смартфоне номер для RPI.

Для запуска и управления Linphonec в режиме демона, используется утилита Linphonecsh.

Первоначально при запуске необходима инициализация клиента linphonecsh -init. При выполнении этой команды происходит запуск консольного клиента, без загрузки конфигурационного файла.
Чтобы при запуске выполнялось чтение конфигурационного файла, возможность видео звонка и автоматического ответа на входящие вызовы запустим с флагами — с — V -a:

/home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonecsh init -c /home/pi/.linphonerc -V -a

Сейчас можем управлять консольным клиентом из командной строки ОС и MajorDoMo.

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

/home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonecsh dial XXXXX 

Первый шаг, можно сказать сделан.

Подключение кнопки и работа с GPIO




В Raspberry Pi имеется ряд портов GPIO (General Purpose Input/Output) это интерфейс. который содержит Входы и Выходы общего назначения, к которым можно подключать разнообразные исполнительные устройства, в нашем случае простую кнопку.

Почти любой контакт GPIO (есть несколько зарезервированных) можно установить в одно из двух состояний: «выход» (он же OUT или логическая 1) или «вход» (IN или логический 0). Напряжение на выходе составляет 3,3В.

Для своей кнопки я буду использовать два самых правых контакта в верхнем ряду. Разъём #38 (GPIO20) будет установлен на «выход» (OUT), а разъём #40 (GPIO21) — на «вход» (IN).

Для подключения к гребенки GPIO используются перемычки BBJ. Рекомендуется проводить подключение при отключенной малинки от сети.

Создадим два скрипта. Первый используется для инициализации портов GPIO, второй для команд управления утилиты Linphonecsh.

Bash скрипт для инициализации портов GPIO:

sudo nano /usr/local/bin/gpio21.sh

и вставляем содержимое

gpio21.sh
#! /bin/bash
# Set up GPIO20 and set to output
echo 20 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio20/direction
echo 1 > /sys/class/gpio/gpio20/value
# Set up GPIO21 and set to input
echo 21 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio21/direction

Делаем файл исполняемым:

sudo chmod +x  /usr/local/bin/gpio21.sh

Второй скрипт для набора номера по нажатию кнопки, я решил сделать на PHP, для последующей интеграции с систему домашней автоматизации MajorDoMo. По нажатию кнопки, меняется состояние порта 21, система периодически считывает значение порта 21 и в случае его изменения отправляет команду набора номера утилите Linphonecsh.

sudo nano /usr/local/bin/dial.php

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

dial.php
<?php
$old_state = 0;
while(true)
{
$state = file_get_contents('/sys/class/gpio/gpio21/value');
if ( $state != $old_state)
{
if ( $state == 1 )
{
//Making new call
echo «make »;
exec («sudo -u pi /home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonecsh dial sip: ХХХХХ@sip.zadarma.com»);
usleep(200000);
}
$old_state = $state;
}
usleep(20000);
}
?>

Делаем файл исполняемым.

Далее прописываем три строчки в самый конец файла автозагрузки:

  1. скрипт инициализации портов GPIO
  2. запуск утилиты управления в режиме автоответа и поддержкой передачи видео
  3. PHP скрипт набора номера.

crontab -e


@reboot sudo /usr/local/bin/gpio21.sh
@reboot sudo -u pi /home/pi/linphone-desktop/OUTPUT/no-ui/bin/linphonecsh init -c /home/pi/.linphonerc -V -a
@reboot sudo php /usr/local/bin/dial.php

Перегружаем наш Raspberry, sudo reboot. После перезапуска наш видеофон готов к использованию.

Дальше при желании и возможности — интеграции в систему домашней автоматизации, подключение к своему SIP серверу и т.д.

Нагрузка на RPI во время ожидания и при совершении видео звонка
Нагрузка на RPI во время ожидания и при совершении видео звонка:





Небольшое отступление в качестве заключения


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

При создании хотел бы, чтоб выполнялись следующие критерии, или хотя бы два из трёх:

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

+13
4,9k 74
Комментарии 7

Рекомендуем