Автоинформатор для openHAB 2

Далее описывается пример настройки взаимодействия sip агента baresip с системой автоматизации openHAB2 на уровне протокола mqtt.

Инструкция предполагает что:

  • У вас есть sip аккаунт (локальный или глобальный).
  • В сети присутвует настроенный сервер с системой автоматизации openHAB.
  • В сети присутвует настроенный mqtt броккер (mosquitto).
  • Установка производится на компьютер Raspberry Pi 3 B+ (OS: Raspbian 9.9 stretch, Kernel: armv7l Linux 4.19.50-v7+)

Сборка и настройка агента baresip

Baresip это кроссплатформенный, модульный SIP агент с поддержкой аудио и видео.

Активируем аудио выход Raspberry Pi

В конфигурационном файле загрузки

sudo vi /boot/config.txt

Добавим настройки

# enable audio
dtparam=audio=on
# no sound from hdmi
hdmi_ignore_edid_audio=1
hdmi_force_edid_audio=1

Пергружаем систему для применения параметров

sudo reboot

Установка дополнительных пакетов

Для сборки агента необходимы следующие пакеты

sudo apt -y install build-essential libmosquitto-dev libalsaplayer0 libasound2-dev libssl-dev alsaplayer

Сборка агента

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

Скачиваем исходные коды агента и необходимых для сборки библиотек

В архиве

wget http://www.creytiv.com/pub/rem-0.6.0.tar.gz
wget http://www.creytiv.com/pub/re-0.6.0.tar.gz
wget http://www.creytiv.com/pub/baresip-0.6.3.tar.gz

Или GIT

git clone https://github.com/creytiv/re.git
git clone https://github.com/creytiv/rem.git
git clone https://github.com/alfredh/baresip.git

Архивы необходимо распаковать для дальнейшей работы

tar -xf re-0.6.0.tar.gz 
tar -xf rem-0.6.0.tar.gz 
tar -xf baresip-0.6.3.tar.gz 

Производим сборку и установку

cd re-0.6.0/
make
sudo make install
sudo ldconfig 
cd ../rem-0.6.0/
make
sudo make install
sudo ldconfig 
cd ../baresip-0.6.3/
make
sudo make install

Настройка агента

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

baresip

Для выхода нажимаем клавишу q

Производим настройку sip аккаунта

vi .baresip/accounts

Пример настроки локального аккаунта

# локальный абонент сервера asterisk с номером 110 паролем password и включенным режимом автоответа
<sip:110@192.168.0.11>;auth_pass=password;answermode=auto

ВАЖНО! Колличество аккаунтов в настройках агента не ограничено. Можно использовать любые сервисы и в дальнейшем управлять звонками так как будет необходимо.

Производим настройку конфигурации

vi .baresip/config

Далее показываю изменения относительно стандартного файла конфигурации

# комментирую источник звука по умолчанию
#audio_source           alsa,default
# в качестве источника звука указываю указываю локальный файл (формат файла зависит от настроек конфигурации)
audio_source            aufile,/home/pi/t1.wav

# раскомментирую модуль для работы с файлами
module                  aufile.so

# раскомментирую модуль для работы с mqtt
module_app              mqtt.so

# прописываю настройки MQTT броккера
mqtt_broker_host        192.168.0.11 
mqtt_broker_port        1883
mqtt_broker_clientid    baresip110 # не обязательный параметр
#mqtt_broker_user       user
#mqtt_broker_password   password
mqtt_basetopic          baresip/110 # указаваю топик который будет использоваться

Пробуем запустить агент

baresip

Если все настроенно корректно, то должны увидеть такой вывод

baresip v0.6.3 Copyright (C) 2010 - 2019 Alfred E. Heggestad et al.
Local network address:  IPv4=wlan0|192.168.0.12 
aucodec: PCMU/8000/1
aucodec: PCMA/8000/1
ausrc: alsa
auplay: alsa
ausrc: aufile
medianat: stun
medianat: turn
medianat: ice
Populated 1 account
Populated 3 contacts
mqtt: connecting to broker at 192.168.0.11:1883 as baresip110 topic baresip/110
mqtt: Publishing on /baresip/110/event, subscribing to /baresip/110/command/+
mqtt: module loaded
Populated 2 audio codecs
Populated 0 audio filters
Populated 0 video codecs
Populated 0 video filters
baresip is ready.
mqtt: connected to broker at 192.168.0.11:1883
mqtt: subscribed to pattern '/baresip/110/command/+'
110@192.168.0.11: {0/UDP/v4} 200 OK (FPBX-14.0.13.4(15.7.1)) [1 binding]
All 1 useragent registered successfully! (35 ms)

Для выхода нажимаем клавишу q

Подготовим systemd юнит для запуска

sudo vi /etc/systemd/system/baresip.service

Следующего содержания

[Unit]
Description=baresip
After=syslog.target
After=network.target

[Service]
Type=simple
User=pi
Group=pi
ExecStart=/usr/local/bin/baresip
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Активируем автозагрузку при старте системы и запускаем

sudo systemctl enable baresip
sudo systemctl start baresip

Подготовка аудиофайлов

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

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

Агент baresip по умолчанию использует формат "PCMU/8000/1", поэтому заранее подготовленные mp3 файлы я конвертирую в данный формат

sudo ffmpeg -i t1.mp3 -ar 8000 -ac 1 t1.wav 
sudo ffmpeg -i t2.mp3 -ar 8000 -ac 1 t2.wav 
sudo ffmpeg -i t3.mp3 -ar 8000 -ac 1 t3.wav 

ВАЖНО! В данном примере звуковые файлы расположены в каталоге /home/pi/ (так же указано ранее в конфигурационном файле).

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

Подготовленные ранее файлы уже сконвертированы в формат mono, поэтому использую такую команду:

ffmpeg -i input.wav -af "adelay=1000" output.wav

Взаимодействие с mqtt броккером

Проверим как baresip обрабатывает очередь сообщений.

Откроем терминал и подпишемся на топик событий (был указан при запуске)

mosquitto_sub -h 192.168.0.11 -v -t /baresip/110/event

При запуске сервиса агента мы увидим событие регистрации

/baresip/110/event {"type":"REGISTER_OK","class":"register","accountaor":"sip:110@192.168.0.11","param":"200 OK"}

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

Для этого в новом терминале выполним команду

mosquitto_pub -h 192.168.0.11 -t /baresip/110/command/ -m '{"command":"dial","params":"111"}'

В терминале с топиком событий увидим соответствующие события, а абонент 111 ответив на звонок услышит содержимое файла /home/pi/t1.wav указанного ранее в конфигурационном файле агента.

/baresip/110/event {"type":"CALL_RINGING","class":"call","accountaor":"sip:110@192.168.0.11","direction":"outgoing","peeruri":"sip:111@192.168.0.11","id":"5f4bae0817c6244f","param":"sip:111@192.168.0.11"}
/baresip/110/event {"type":"CALL_RINGING","class":"call","accountaor":"sip:110@192.168.0.11","direction":"outgoing","peeruri":"sip:111@192.168.0.11","id":"5f4bae0817c6244f","param":"sip:111@192.168.0.11"}
/baresip/110/event {"type":"CALL_ESTABLISHED","class":"call","accountaor":"sip:110@192.168.0.11","direction":"outgoing","peeruri":"sip:111@192.168.0.11","id":"5f4bae0817c6244f","param":"sip:111@192.168.0.11"}
/baresip/110/event {"type":"CALL_CLOSED","class":"call","accountaor":"sip:110@192.168.0.11","direction":"outgoing","peeruri":"sip:111@192.168.0.11","id":"5f4bae0817c6244f","param":"Connection reset by peer"}

Для завершения вызова отправим команду

mosquitto_pub -h 192.168.0.11 -t /baresip/110/command/ -m '{"command":"hangup"}'

Управление сообщениями и вызовами из openHAB

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

ВАЖНО! Настроки производились в системе openHAB 2.4.0 Release Build, с установленными дополнениями MQTT Binding и JSONPath Transformation.

Для начала нам необходимо создать файл конфигурации источников информации.

vi /etc/openhab2/things/baresip.things 

Прописываем конфигурацию mqtt брокера, топиков событий и управления baresip.

Bridge mqtt:broker:rpi3 [ host="192.168.0.11", port=1883, secure=false, clientID="openHAB2_baresip" ] {
 Thing topic baresip {
  Channels:
   Type string : event [
    stateTopic="/baresip/110/event",
    transformationPattern="JSONPATH:$.type" 
    ]
   Type string : command [
    commandTopic="/baresip/110/command/"
    ]
  }
}

ВАЖНО! Правилом transformationPattern мы извлекаем из топика только состояние переменной type.

Переменная type принимает значения:

  • REGISTER_OK - регистрация агента прошла успешно (sip аккаунт активен)
  • CALL_RINGING - входящий звонок
  • CALL_ESTABLISHED - соединение установлено
  • CALL_RTCP - получение служебных пакетов во время звонка
  • CALL_CLOSED - звонок завершен

Создаем файл конфигураци объектов

vi /etc/openhab2/items/baresip.items 

Прописываем четыре объекта

// указатель на номер сообщения
Number  baresip_message
// переключатель формирующий события 
Switch  baresip_call
// строка получаемая из топика событий
String  baresip_state "type" { channel="mqtt:topic:local:baresip:event" }
// строка отправляемая в топик управления
String  baresip_command { channel="mqtt:topic:local:baresip:command" }

Создаем файл конфигураци интерфейса

vi /etc/openhab2/sitemaps/baresip.sitemap 

Интерфейс будет состоять из трех элементов

sitemap baresip label="Агент baresip" {
// элемент отображающий значение переменной type
Text item=baresip_state label="Статус" icon="settings"
// элемент выбора сообщения
Selection item=baresip_message label="Сообщение" icon="soundvolume" mappings=["1"="Вариант 1", "2"="Вариант 2", "3"="Вариант 3"]
// элемент управления вызовом
Switch item=baresip_call label="Вызов" icon="recorder" mappings=["ON"="Позвонить", "OFF"="Завершить"]
}

Создаем файл правил обработки событий

vi /etc/openhab2/rules/baresip.rules 

Для демонстрации работы создадим три правила

// правило устанавливает начальное значение при старте системы
rule "baresip init"
when
    System started
then
    postUpdate(baresip_message, 1)
end

// правило отправляет команду в топик управления baresip которая задает проигрываемый файл
rule "baresip message"
when
        Item baresip_message received update
then
        baresip_command.sendCommand("{\"command\":\"ausrc\",\"params\":\"aufile,/home/pi/t"+baresip_message.state+".wav\"}")
end

// правило формирующее команды начала и завершения вызова при получении событий от переключателя
rule "baresip call"
when
        Item baresip_call received command
then
        if(receivedCommand == ON) baresip_command.sendCommand("{\"command\":\"dial\",\"params\":\"111\"}")
        else baresip_command.sendCommand("{\"command\":\"hangup\"}")
end

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

Опубликовано: