MAJORDOMO + VoIP

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

ksgroup
Сообщения: 135
Зарегистрирован: Ср дек 19, 2012 10:35 am
Откуда: Ukraine/Kiev
Благодарил (а): 7 раз
Поблагодарили: 14 раз

MAJORDOMO + VoIP

Сообщение ksgroup » Пт июл 05, 2013 9:23 am

Имеется у меня на сервере IP АТС Asterisk. Разруливает входящие и исходящие звонки по пяти IP телефонам в доме. Решил я подружить умный дом с телефонией. И вот уже при каждом входящем звонке Алиса мне сообщает кто звонит. Понятное дело что для этого в линии должна присутствовать функция определения номера. В самом Asteriske в командах диалплана я указал вызов системной команды в которой номер звонящего передается в свойство CID объекта PHONE. В MJ создал объект PHONE со свойством CID и сценарий обрабатывающий изменение этого свойства.
Если тема интересна сообществу - опишу подробнее.

Теперь есть идея научить Алису в определенных ситуациях звонить по VoIP и сообщать нужную информацию. Для этого необходим софтфон умеющий получать команды из других программ. Кроме того этот софтфон должен работать в системе LINUX (так как у меня UBUNTU SERVER) да еще и без GUI. К сожалению на данный момент ничего такого не нашел. Возможно плохо искал. Если кто то из сообщества может подсказать какую то информацию по этому поводу буду очень рад. Возможно имеются какие то модули PHP (или других языков программирования) для работы с VoIP?
CubieBoard A10 - основной сервер Majordomo
Raspberry Pi - цифровая мини АТС ASTERISK
Arduino - блок управления реле, электросчетчик, счетчики воды, управление вентиляционной системой, СКУД.
Аватара пользователя
sergejey
Site Admin
Сообщения: 4284
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 75 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: MAJORDOMO + VoIP

Сообщение sergejey » Пт июл 05, 2013 11:36 am

Отличная идея, подробности будут весьма кстати! В том числе по железу -- давно хочу организовать дома что-то вроде интеркомов с подключением телефонной сети, домофона и прочее.

Что касается "звонить" с Алисы -- а Asterisk не может прокручивать сценарии на каком-нибудь VoiceXML? Т.е. звонить сам по себе и чего-то говорить?

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
ksgroup
Сообщения: 135
Зарегистрирован: Ср дек 19, 2012 10:35 am
Откуда: Ukraine/Kiev
Благодарил (а): 7 раз
Поблагодарили: 14 раз

Re: MAJORDOMO + VoIP

Сообщение ksgroup » Пт июл 05, 2013 3:08 pm

Да тут все просто. Создал класс 'TELEPHONIC'. В нем создал объект 'PHONE' и свойство 'CID'. Создал метод 'ring' в котором прописал код:

$this->setProperty('CID',$params['cid']);

Потом открыл объект 'PHONE' и его метод 'ring' настроил на вызов сценария "PhoneRing".

Сценарий "PhoneRing":

$cid = gg('PHONE.CID'); Получаем номер телефона из переменной.
$mes=''; Очищаем сообщение

if ($cid == '0441234567'){$mes = 'Дима звонит.';} ; Можно создать список телефонов которые Алиса будет называть по именам

//########################################################################
if ($mes == ''){
$kod = substr($cid,0,3);
$num1 = substr($cid,3,3);
$num2 = substr($cid,6,2);
$num3 = substr($cid,8,2);
$mes = 'Входящий вызов от абонента неизвесной сети с кодом '.substr($kod,0,1).' '.substr($kod,1,2).' и номером ';

if ($kod == '044'){$mes = 'Входящий вызов от абонента городской сети с номером ';}

if ($kod == '050'){$mes = 'Входящий вызов от абонента сети МТС с номером ';}
if ($kod == '095'){$mes = 'Входящий вызов от абонента сети МТС с номером ';}
if ($kod == '099'){$mes = 'Входящий вызов от абонента сети МТС с номером ';}

if ($kod == '066'){$mes = 'Входящий вызов от абонента сети ДЖИНС с номером ';}

if ($kod == '063'){$mes = 'Входящий вызов от абонента сети ЛАЙФ с номером ';}
if ($kod == '093'){$mes = 'Входящий вызов от абонента сети ЛАЙФ с номером ';}

if ($kod == '067'){$mes = 'Входящий вызов от абонента сети КИЕВСТАР с номером ';}
if ($kod == '096'){$mes = 'Входящий вызов от абонента сети КИЕВСТАР с номером ';}
if ($kod == '097'){$mes = 'Входящий вызов от абонента сети КИЕВСТАР с номером ';}
if ($kod == '098'){$mes = 'Входящий вызов от абонента сети КИЕВСТАР с номером ';}

if ($kod == '068'){$mes = 'Входящий вызов от абонента сети БИЛАЙН с номером ';}

if ($kod == '091'){$mes = 'Входящий вызов от абонента сети ЮТЕЛ с номером ';}

if ($kod == '092'){$mes = 'Входящий вызов от абонента сети ИНТЕРТЕЛЕКОМ с номером ';}

$mes = $mes.$num1.'-'.$num2.'-'.$num3;
}

say($mes); Ну и собственно тут Алиса произносит подготовленное сообщение.
sg('PHONE.cid',''); Очищаем переменную.


В Asterisk-е в плане набра входящего вызова я вписал строку:
exten => s, 1, TrySystem(/usr/bin/php /var/majordomo/objects/index.php object:PHONE op:m m:ring cid:${CALLERID(number)})


По железу:
1.У меня на систему UBUNTU установлен Asterisk 1.8. На этой же машине установлен и MajorDoMo. Читал в сети что можно установить Asterisk на Raspberry Pi, но пока не пробовал.

2. VoIP шлюз SPA-3102. Он имеет 1 FXO - к которому подключена городская телефонная линия, и 1FXS - сюда у меня подключен аналоговый DECT телефон Panasonic.

3. 4 аппарата Dynamix IP Phone E210 установлены в комнатах и подключены витой парой к роутеру.

4. GSM шлюз сделан на базе модема Huawei E1550 и программного модуля Asterisk dongle.
Домофона к сожалению пока нет, но он планируется.
За это сообщение автора ksgroup поблагодарили (всего 2):
Bolik.Stav (Вс янв 18, 2015 1:51 pm) • mirsum (Вт окт 06, 2015 11:30 pm)
Рейтинг: 2.33%
CubieBoard A10 - основной сервер Majordomo
Raspberry Pi - цифровая мини АТС ASTERISK
Arduino - блок управления реле, электросчетчик, счетчики воды, управление вентиляционной системой, СКУД.
immortal
Сообщения: 1138
Зарегистрирован: Вт янв 29, 2013 9:16 am
Откуда: Белозерск
Благодарил (а): 16 раз
Поблагодарили: 400 раз
Контактная информация:

Re: MAJORDOMO + VoIP

Сообщение immortal » Пт июл 05, 2013 10:20 pm

не понял зачем софтфон, когда проще звонить астериском используя call файлы предварительно их генерировать алисой.
только генерить надо не в папке outgoing, а в любой другой, а потом перемещать в outgoing
Lubuntu на cubieboard2 + ds9490R
DietPi на Orange Pi PC + 1wire на esp8266 с прошивкой Homes-smart.ru
ksgroup
Сообщения: 135
Зарегистрирован: Ср дек 19, 2012 10:35 am
Откуда: Ukraine/Kiev
Благодарил (а): 7 раз
Поблагодарили: 14 раз

Re: MAJORDOMO + VoIP

Сообщение ksgroup » Пт июл 05, 2013 10:31 pm

Да вся проблема в том что я Asterisk совершенно не знаю. Но спасибо за подсказку! Погуглю на тему call файлов.
CubieBoard A10 - основной сервер Majordomo
Raspberry Pi - цифровая мини АТС ASTERISK
Arduino - блок управления реле, электросчетчик, счетчики воды, управление вентиляционной системой, СКУД.
Alien
Сообщения: 191
Зарегистрирован: Пт дек 20, 2013 4:46 pm
Благодарил (а): 72 раза
Поблагодарили: 38 раз

Re: MAJORDOMO + VoIP

Сообщение Alien » Пт дек 20, 2013 4:51 pm

Создание телефонного справочника для телефонов cisco 7940:
Создать сценарий createDxml и запускать его каждый час.
Код:

$xmlfile = "/var/www/asterisk/directory.xml"; // файл, на который указано в настройках телефона
$ufile = "/etc/asterisk/users.conf"; // конфигурационный файл asterisk.
$title = "Phonebook"; // Название меню
$prompt = "Select the User"; //Строка подписи

if (is_readable($ufile)) { //Проверяем конф на доступность
if ($conf = parse_ini_file ($ufile,true)) {
$dxf = fopen ($xmlfile, "w"); //Создаем xml файл телефонного справочника
fwrite ($dxf,"<CiscoIPPhoneDirectory>\n");
fwrite ($dxf,"<Title>$title</Title>\n");
fwrite ($dxf,"<Prompt>$prompt</Prompt>\n");
foreach ($conf as $array) { //Перебираем массив и добавляем все вхождения в xml
$name = $array["fullname"];
$num = $array["cid_number"];
if ($num) {
fwrite ($dxf,"<DirectoryEntry>\n");
fwrite ($dxf,"\t<Name>$name</Name>\n");
fwrite ($dxf,"\t<Telephone>$num</Telephone>\n");
fwrite ($dxf,"</DirectoryEntry>\n");
};
};
fwrite ($dxf,"</CiscoIPPhoneDirectory>\n");
};
};

fclose($dxf);

У такого способа есть два минуса.
Первый - безопасность. Для парсинга номеров нужно дать права на чтение /etc/asterisk/users.conf
всем пользователям, что не есть гуд. При желании злоумышленник вытянет заодно и пароли sip.
Решается просто - ложим этот скрипт в папку scripts. Называем его createDxml.php
Затем настраиваем cron на запуск каждый час от имени asterisk:
sudo crontab -e -u asterisk
В самом низу добавляем строку запуска каждый час:
0 * * * * /var/www/scripts/createDxml.php
После строки не забываем добавлять одну пустую - это знак крону что файл закончен.


Второй недостаток данного метода - ограничение телефона на 31 запись в xml.
Для дома может быть и достаточно, тогда можно оставить как есть.
Если телефонный справочник больше, то нужно организовать поиск.
В настройках телефона указываем путь не к directory.xml, а directory.php.
Создаем в /var/www/asterisk/directory.php
В файле нужно проставить IP-адрес сервера.
Код:

#!/usr/bin/php
<?php
$URLPHP="http://IP АДРЕС СЕРВЕРА/asterisk/directory.php";
$URLXML="http://IP АДРЕС СЕРВЕРА/asterisk/directory.xml";
$title = "Phonebook";
switch ($_GET[op]) {
case '':
echo "<CiscoIPPhoneInput>\n";
echo "<Title>$title</Title>\n";
echo "<Prompt>Please Enter User Last Name</Prompt>\n";
echo "<URL>$URLPHP?op=search</URL>\n";
echo "<InputItem>\n";
echo "<DisplayName>Last Name</DisplayName>\n";
echo "<QueryStringParam>lastname</QueryStringParam>\n";
echo "<DefaultValue />\n";
echo "<InputFlags>A</InputFlags>\n";
echo "</InputItem>\n";
echo "<InputItem>\n";
echo "<DisplayName>Number</DisplayName>\n";
echo "<QueryStringParam>number</QueryStringParam>\n";
echo "<DefaultValue />\n";
echo "<InputFlags>N</InputFlags>\n";
echo "</InputItem>\n";
echo "</CiscoIPPhoneInput>\n";
break;

case 'search':
$user = simplexml_load_file ($URLXML);
echo "<CiscoIPPhoneDirectory>\n";
echo "<Title>$title</Title>\n";
echo "<Prompt>Select the User</Prompt>\n";
foreach ($user->DirectoryEntry as $entry) {
if ($_GET[lastname]) {
if (preg_match("/".mb_strtolower($_GET[lastname])."/", mb_strtolower($entry->Name))) {
echo "<DirectoryEntry>\n";
echo "<Name>$entry->Name</Name>\n";
echo "<Telephone>$entry->Telephone</Telephone>\n";
echo "</DirectoryEntry>\n";
};
} else {
if (preg_match("/".$_GET[number]."/", $entry->Telephone)) {
echo "<DirectoryEntry>\n";
echo "<Name>$entry->Name</Name>\n";
echo "<Telephone>$entry->Telephone</Telephone>\n";
echo "</DirectoryEntry>\n";
};
};
};
echo "</CiscoIPPhoneDirectory>\n";
break;
}
?>
Ubuntu на Banana pi M2U Connect
Alien
Сообщения: 191
Зарегистрирован: Пт дек 20, 2013 4:46 pm
Благодарил (а): 72 раза
Поблагодарили: 38 раз

Re: MAJORDOMO + VoIP

Сообщение Alien » Пт дек 27, 2013 4:50 pm

По call файлам можно в systemStates stateChanged добавить код для дозвона. Как пример Security.stateChanged

if (gg("Security.stateColor") == "red") {
$calltmp = "/var/spool/asterisk/tmp/security_red.call";
$calldir = "/var/spool/asterisk/outgoing/security_red.call";
$callnumber = "SIP/200"; //Указываем внутренний на который звонить. Или внешний через донгл: Dongle/dongle0/holdother:0505555555
$dirmessage = "/var/www/cached/voice/";
$message = (md5("Статус системы безопасности изменился на ".gg("Security.stateTitle").". ".implode(". ",gg("Security.stateDetails"))));
$callfile = fopen ($calltmp, "w");
fwrite ($callfile,"Channel: $callnumber\n");
fwrite ($callfile,"Callerid: 299\n");
fwrite ($callfile,"MaxRetries: 2\n");
fwrite ($callfile,"RetryTime: 60\n");
fwrite ($callfile,"WaitTime: 60\n");
fwrite ($callfile,"Context: majordomo\n");
fwrite ($callfile,"Extension: s\n");
fwrite ($callfile,"Priority: 1\n");
fwrite ($callfile,"Set: playfile=$dirmessage$message\n");
fwrite ($callfile,"Archive: Yes\n");
fclose($callfile);
copy ($calltmp,$calldir);
};
Астериск дозванивается по указанному номеру и сообщает статус и ошибку из голосового кеша Алисы.
Ubuntu на Banana pi M2U Connect
ksgroup
Сообщения: 135
Зарегистрирован: Ср дек 19, 2012 10:35 am
Откуда: Ukraine/Kiev
Благодарил (а): 7 раз
Поблагодарили: 14 раз

Re: MAJORDOMO + VoIP

Сообщение ksgroup » Пт дек 27, 2013 6:49 pm

Alien писал(а):По call файлам можно в systemStates stateChanged добавить код для дозвона. Как пример Security.stateChanged

if (gg("Security.stateColor") == "red") {
$calltmp = "/var/spool/asterisk/tmp/security_red.call";
$calldir = "/var/spool/asterisk/outgoing/security_red.call";
$callnumber = "SIP/200"; //Указываем внутренний на который звонить. Или внешний через донгл: Dongle/dongle0/holdother:0505555555
$dirmessage = "/var/www/cached/voice/";
$message = (md5("Статус системы безопасности изменился на ".gg("Security.stateTitle").". ".implode(". ",gg("Security.stateDetails"))));
$callfile = fopen ($calltmp, "w");
fwrite ($callfile,"Channel: $callnumber\n");
fwrite ($callfile,"Callerid: 299\n");
fwrite ($callfile,"MaxRetries: 2\n");
fwrite ($callfile,"RetryTime: 60\n");
fwrite ($callfile,"WaitTime: 60\n");
fwrite ($callfile,"Context: majordomo\n");
fwrite ($callfile,"Extension: s\n");
fwrite ($callfile,"Priority: 1\n");
fwrite ($callfile,"Set: playfile=$dirmessage$message\n");
fwrite ($callfile,"Archive: Yes\n");
fclose($callfile);
copy ($calltmp,$calldir);
};
Астериск дозванивается по указанному номеру и сообщает статус и ошибку из голосового кеша Алисы.
А вот что при этом должно быть в контексте "majordomo" в экстеншне "s"?
Мне так и не удалось добиться проигрывания файла.
CubieBoard A10 - основной сервер Majordomo
Raspberry Pi - цифровая мини АТС ASTERISK
Arduino - блок управления реле, электросчетчик, счетчики воды, управление вентиляционной системой, СКУД.
Alien
Сообщения: 191
Зарегистрирован: Пт дек 20, 2013 4:46 pm
Благодарил (а): 72 раза
Поблагодарили: 38 раз

Re: MAJORDOMO + VoIP

Сообщение Alien » Пт дек 27, 2013 8:53 pm

Ну, варианты по проигрыванию у меня были такие:
1. wav файл - астериск играет именно их. Звук я формирую фестивалем, как в примерах было, с нюансом битрейта в 8000:

echo "$1" | text2wave -F 8000 -o /var/www/cached/voice/"$2" -eval "(voice_msu_ru_nsh_clunits)"
aplay /var/www/cached/voice/"$2" > /dev/null 2>&1

2. Имя файла это хеш md5 от произносимой фразы, астериску расширение указывать не нужно. Если Алиса говорит через гугл, то нужно еще предварительно запустить mpg123 для перекодировки из mp3 в wav.

Вот контекст астериска для дозвона:
[majordomo]
exten => s,1,Answer
exten => s,n,Wait(1)
exten => s,n,Playback(${playfile})
exten => s,n,hangup

Ну а вообще нужно посмотреть что астериск в лог выдает: asterisk -rv.
Ubuntu на Banana pi M2U Connect
ksgroup
Сообщения: 135
Зарегистрирован: Ср дек 19, 2012 10:35 am
Откуда: Ukraine/Kiev
Благодарил (а): 7 раз
Поблагодарили: 14 раз

Re: MAJORDOMO + VoIP

Сообщение ksgroup » Сб дек 28, 2013 5:15 pm

Alien писал(а):Ну, варианты по проигрыванию у меня были такие:
1. wav файл - астериск играет именно их. Звук я формирую фестивалем, как в примерах было, с нюансом битрейта в 8000:

echo "$1" | text2wave -F 8000 -o /var/www/cached/voice/"$2" -eval "(voice_msu_ru_nsh_clunits)"
aplay /var/www/cached/voice/"$2" > /dev/null 2>&1

2. Имя файла это хеш md5 от произносимой фразы, астериску расширение указывать не нужно. Если Алиса говорит через гугл, то нужно еще предварительно запустить mpg123 для перекодировки из mp3 в wav.

Вот контекст астериска для дозвона:
[majordomo]
exten => s,1,Answer
exten => s,n,Wait(1)
exten => s,n,Playback(${playfile})
exten => s,n,hangup

Ну а вообще нужно посмотреть что астериск в лог выдает: asterisk -rv.
Вот теперь все заработало. Спасибо.

Вижу что у вас достаточно знаний об Астериске, поэтому хочу задать вопрос. Вот у меня есть несколько внутренних номеров в Астериксе, но парочку из них удаленные, которые подключены через интернет. Так уж сложилось что они подключены не всегда, а только тогда когда удаленный аппарат включен (ну есть такая необходимость что бы он был включен не всегда.) Очень хотелось бы как то из МДМ иметь возможность видеть в реальном времени включен ли удаленный SIP аппарат. К сожалению на удаленном конце динамические IP поэтому простым пингом тут не отделаться. Хотелось бы как то получать инфу от астериска о подключенных в данный момент аппаратах.
CubieBoard A10 - основной сервер Majordomo
Raspberry Pi - цифровая мини АТС ASTERISK
Arduino - блок управления реле, электросчетчик, счетчики воды, управление вентиляционной системой, СКУД.
Ответить