AF
Asterisk Forum
обсуждения телефонии, VoIP и IP-PBX
12разделов
5 423тем
34 385сообщений
← К списку тем

Ограничение минут исходящих по транкам

Asterisk GUI 17 сообщений -
#1

Не для кого не секрет, что у нынешних GSM операторов имеются бонусные минуты для исходящих звонков в соответствии с их тарифными планами. Теперь ситуация. Имеется Asterisk 1.6+FreePBX 2.9 с 20 GSM каналами. В качестве GSM шлюзов используются модемы Huawei E1550 под управлением chan_dongle. Необходимо прописать на каждый транк ограничение по колличеству исходящих звонков с него. Причем на некоторых транках ограничение должно быть суточное, а на некоторых месячное. Я знаю, что на А2Billing это было реализовано. Кто-то сталкивался с этим? Может есть какие-то идеи? Не очень хочется спрыгивать с FreePBX. Все уже отлажено долгими трудами и работает как по маслу. Вот только осталось добавить приятную мелочь для экономии средств. Буду очень благодарен за помощь.
#2

Сделать можно запрашивая из CDR длительность пор звонкам, но во FreePBX это несколько неудобно делать.
Имхо Вам в коммерческий саппорт.

_________________
Gentoo Linux || Asterisk 11.2-cert3
Решения телефонии на базе Asterisk || http://it-need.ru
#3

samorus писал(а):
Не для кого не секрет, что у нынешних GSM операторов имеются бонусные минуты для исходящих звонков в соответствии с их тарифными планами.


Для a2billing - http://www.asterisk2billing.org/cgi-bin/trac.cgi/ticket/869
Альтернативный скрипт.

#!/usr/bin/perl

# load module
use Asterisk::AGI;
use DBI;
#use date::Format;



# connect
my $dbh = DBI->connect("DBI:Pg:dbname=asterisk;host=127.0.0.1", "asterisk_user", "passwd", {'RaiseError' => 1});


my %trunks=("name1" => "SIP/994",
"name2" => "SIP/993",
"name3" => "SIP/992",
"name4" => "SIP/991"); #89839

my %trunks_id=("name1" => "994",
"name2" => "993",
"name3" => "992",
"name4" => "991");

my $Default_trunk="SIP/63762xx";
my $Default_trunk_id="63762xx";

my %calls=();
my @calls_order=();

my $LIMIT=2000*60;
my $min=$LIMIT;
my $min_trunk="name1";

foreach $trunk (keys(%trunks)){
my $sth = $dbh->prepare("SELECT sum(billsec) AS calltime FROM cdr WHERE
date_trunc('month',calldate) = date_trunc('month',now()) AND dstchannel LIKE '$trunks{$trunk}-%' ;");
$sth->execute();

while(my $ref = $sth->fetchrow_hashref()) {
if($ref->{'calltime'} < $LIMIT){
$calls{$trunk}=$ref->{'calltime'};

if ($min > $ref->{'calltime'} ){
$min=$ref->{'calltime'};
$min_trunk=$trunk;
}

}
if(not $ref){
$calls{$trunk}=0;
}
}#end while
}

$dbh->disconnect();

#@calls_order = sort { $calls{$b} cmp $calls{$a} } keys %calls;
@calls_order = sort { $calls{$a} $calls{$b} } keys %calls;


#foreach $trunk (@calls_order){
# print "$trunk = $calls{$trunk}\n";
# $AGI->verbose("$trunk = $calls{$trunk}\n",3);
#}
#print "min $min_trunk\n";
#$AGI->verbose("min $min_trunk\n",3);




$|=1;
my $AGI = new Asterisk::AGI;
$AGI->setcallback(\&mycallback);
my %input = $AGI->ReadParse();
sleep(1);
my $num = $input{'extension'};
my $caller_id = $input{'callerid'};
if (!$num) {
exit;
}

my $num1 = substr($num,1,6);
my $syscmd1=`perl -ne "print if m/$num1/" /usr/share/asterisk/agi-bin/cods.txt`;
chomp($syscmd1);
if($syscmd1==0){
$AGI->exec('Playback', "/var/lib/asterisk/sounds/record/blocked_call");
exit;
}

my $use_default=1;

#$AGI->stream_file("/var/lib/asterisk/sounds/record/limit_call","*");
$AGI->exec('Playback', "/var/lib/asterisk/sounds/record/limit_call");

$AGI->verbose("Executing Dial $num $num1 $caller_id $syscmd1 \n",3);
foreach $trunk (@calls_order){
$AGI->set_callerid($trunks_id{$trunk});
my $syscmd=`asterisk -r -x "core show channels" | grep "$trunks{$trunk}"| wc -l`;
chomp($syscmd);

if($syscmd==0){
#$AGI->verbose("????? Status $trunks{$trunk} '$ret' '$status'\n",3);
# my $ret=$AGI->exec('Dial', "$trunks{$trunk}/$num");

my $ret=$AGI->exec('Dial', "$trunks{$trunk}/$num|120|L(191664)");
my $status=$AGI->channel_status();

if( ($status==0 || $status==1) && $ret!=1 ){
$AGI->verbose("????? OK! $caller_id $num ret=$ret status=$status syscmd=$syscmd\n",3);
$use_default=0;
last;
}else{
$AGI->verbose("????????? error $caller_id $num $trunks{$trunk}/$num '$ret' status=$status syscmd=$syscmd \n",3);
}
}
}

if($use_default==1){
$AGI->set_callerid($Default_trunk_id);
my $ret=$AGI->exec('Dial', "$Default_trunk/$num");
$AGI->verbose("????????? error_Default_trunk $caller_id $num $Default_trunk/$num ret=$ret \n",3);
}

sleep(1);
exit;

sub mycallback {
my ($returncode) = @_;
&log("CALLBACK");
&cleanup;
#print STDERR "User Disconnected ($returncode)\n";
$AGI->verbose("!!!!!!!!!! ($returncode)\n");
exit($returncode);
}


Придумаешь третий вариант - не сочти за труд, отпиши в личку )
#4

Да я вообще хочу чтонибудь по проще. Типа обычного bin bash скрипта который будет запускаться кроном каждую минуту и выводить значение из * по колличеству секунд на транк и при превышении некоторого значения, выключать транк) А другой скрипт будет включать эти транки в нужный момент...
Просто не очень знаю bin bash.

Предполагаю что это чтото подобное:

`asterisk -rx "dongle show device statistics Modem-1 | grep Seconds of outgoing calls"`
if
"Seconds of outgoing calls" 6000
then

`asterisk -rx "dongle stop now Modem-1"`


А другой скрипт, чтото подобное:


`asterisk -rx "dongle start Modem-1"`



Вот както так.... Только вот как это все правильно написать, уж извините....
#5

Ага. Только бонусные звонки могут тарифицироваться поминутно, соответсвенно есть риск попасть на лишние деньги. Плюс непонятно, когда сбрасывается статистика. так что лучше обращаться к базе.
#6

Статистика сбрасывается при отключении модема или при перезагрузке * . Если второй скрипт будет делать рестарт модемов или * в 12.00, то статистика будет четко отсчитываться. А по поводу поминутной тарификации, тут даже база не поможет. Ведь в базе * счетчик тоже посекундный. Лучше честно говоря выбирать пакеты с посекундной. В моем случае это так. И все-таки, кто нибудь помогите с bin-bash'ом...
#7

Всё конечно зависит от железки, если скрипт не будет грузить машинку сильно, то можно его и раз в минуту запулять..
_________________
Продам виртуальную АТС. Желающим 5% скидка...
#8

Ну я же не поднимаю * на каком нибудь роутере) Стоит полноценная 2ядерная машина с 2 Гб оперативы, рейдовым винтом и т.д. Причем ее единственная функция - "Сервер Asterisk".
#9

После того, как МТС навязало нам платный пакет включенных минут, тема стала актуальной.
Решили как то эту проблему? Поделитесь...
#10

Проще сделать так..делать запрос юссд, приходит ответ с количеством минут.. парсится цифровое значение., если цифра приближается к нулю то отанавливаем данное направление..
#11

а как это реализовать?
#13

Мне вариант с ussd запросом кажется более подходящим, т.к. получаем результат тот, который в биллинге у оператора. Брать из CDR будет неправильно из-за поминутного округления в большую сторону у опсоса. Полагаю приличная погрешность набежит за месяц. А сверх лимитные звонки достаточно дорогие.

Принцип: делать раз в час (ну или кому как надо) ussd запрос, парсить его и включать-отключать транк. Вот только в программировании не силен...
#14

siti писал(а):
Брать из CDR будет неправильно из-за поминутного округления в большую сторону у опсоса.

а я при расчетах беру данные из CDR и тем же запросом округляю поминутно, так же это делает оператор.
только, иногда, данные у меня и у оператора могут отличатся на секунду.
дабы не было косяков, я на всякий пожарный, тем же запросом прибавляю 1 секунду. (лучше больше чем меньше)

_________________
Алексей Милько
#15

siti писал(а):
Мне вариант с ussd запросом кажется более подходящим, т.к. получаем результат тот, который в биллинге у оператора. Брать из CDR будет неправильно из-за поминутного округления в большую сторону у опсоса. Полагаю приличная погрешность набежит за месяц. А сверх лимитные звонки достаточно дорогие.

Принцип: делать раз в час (ну или кому как надо) ussd запрос, парсить его и включать-отключать транк. Вот только в программировании не силен...

опсос какой?
#16

МТС
#17

ну тогда делай запрос юссд *102*1# если память не подводит..в ответ придут минуты..выдергивай их и смотри если меньше 10 минут осталось то тормози соответствующий канал. Ну и как вариант чтоб уведомление отсылалось о том что симку сменить пора. либо если мультисим то команду на ротацию симки.