Автоинформатор для 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 телефонии.