По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:
Привет! Сегодня расскажем про то, как настроить Call Hunting в Cisco Unified Communications Manager (CUCM). Call Hunting позволяет распределять звонки на телефоны, в необходимой последовательности.
Теория
Call Hunting содержит следующие компоненты:
Directory Numbers (DNs) и Voicemail порты: конечные назначения, присваиваются Line Groups;
Line Groups: присваиваются Hunt List’у, к одному Hunt листу можно присвоить больше одной Line группы. В Line группе могут быть настроены различные алгоритмы поиска (Top-Down, Circular, Longest Idle, Broadcast) и другие настройки;
Hunt Lists: Представляет собой упорядоченный список Line групп. Звонок, проходящий через систему Call Hunting’а направляется в первую Line группу в Hunt листе. Если никто не может ответить в этой Line группе, то звонок может быть возвращен в Hunt List, где будет направлен в другую Line группу. Процесс может повторяться до тех пор, пока на звонок не ответят, закончатся Line группы или звонящий повесит трубку;
Hunt Pilots: Hunt Pilot присваивается Hunt List’у, и может быть уникальным DN или ТфОП номером. После набора этого номера начинается процесс Call Hunting’а;
Визуально это можно представить так:
Настройка Call Hunting
Первым делом создаем Line Group:
Для начала необходимо убедиться, что созданы Directory Numbers, присвоенные телефонным аппаратам;
После этого в CM Administration переходим во вкладку Call Routing → Route/Hunt → Line Group, и в открывшемся окне нажимаем Add New;
Здесь в поле Line Group Name указываем называние для Line группы, ниже в поле RNA Reversion Timeout указываем сколько секунд будет звонить каждый телефон в группе, перед тем как будет достигнуто значение No Answer;
В выпадающем списке Distribution Algorithm выбираем алгоритм распределения звонков:
Top Down – каждый новый вызов начинается с номера который стоит первым в списке;
Circular – каждый новый вызов начинается с номера, который в списке был после номера, который принял предыдущий вызов;
Broadcast – все телефоны звонят одновременно; Longest Idle Time – звонок направляется на телефон, который дольше всех был неактивен);
В меню Hunt Options выбираем, что будет происходить со звонком при достижении определенного состояния (No Answer, Busy и Not Available);
В поле Available DN/Route Partition выбираем номера, которые будут добавлены в группу, и в каком порядке будет происходить обзвон. Они будут отображаться в поле Secelted DN/Route Partition. Затем нажимаем Save;
Затем создаем Hunt List:
Переходим во вкладку Call Routing → Route/Hunt → Hunt List и нажимаем Add New;
В поле Name указываем название листа;
Выбираем CUCM группу в поле Cisco Unified Communications Manager Group. Значение по умолчанию – Default;
Нажимаем Save, после чего на странице появится поле Hunt List Member Information;
Нажимаем Add Line Group и добавляем в необходимом порядке Line группы, созданные ранее;
Теперь, как вы могли догадаться, создаем Hunt Pilot :)
Переходим во вкладку Call Routing → Route/Hunt → Hunt Pilot и нажимаем Add New.
В поле Hunt Pilot указываем номер, на который будут поступать звонки;
Если необходимо, то указываем Partition;
В выпадающем меню Hunt List выбираем тот Hunt List, на который будут уходить звонки;
В меню Call Forward Settings можно указать, куда отправлять вызов, если Call Hunting система не может его обработать (состояния No Answer и Busy);
Сегодня поговорим о процессе настройки модуля Callback в FreePBX 13. Как настроить и использовать данный модуль и читайте ниже.
Что это?
Коллбэк (callback) - функционал обратного звонка, который меняет направление вызова на "обратное" - исходящий звонок от абонента путём сброса вызова становится входящим для абонента, то есть IP - АТС набирает номер позвонившего.
Вы спросите, зачем это надо? Данный функционал обычно используется для уменьшения счетов у мобильных операторов и/или счетов при международных звонках. Как правило, вызов данной функции совершается из IVR-меню или настраивается входящий маршрут на CallBack.
Настройка CallBack в FreePBX
Первый шаг крайне прост – в веб-интерфейсе необходимо открыть следующую вкладку: Applications – Callback. Перейдя в меню настройки модуля, нажмите на кнопку + Add Callback
Переходим к настройке доступных опций
Сallback Description – описание вашего коллбэка, полезно если несколько коллбэков используются на вашей АТС
Callback Number – опциональное поле, если оставить пустым, то АТС совершит вызов по номеру, с которого до этого пришёл вызов. В ином случае, АТС совершит вызов по номеру, указанному в данном поле
Delay Before Callback – опциональное поле, интервал (в секундах) между активацией модуля и совершением вызова с АТС. По умолчанию интервал равен нулю
Destination after Callback – маршрутизация вызова после звонка: к примеру можно направить вызов на требуемый номер/ринг-группу/IVR-меню и так далее
Созданные коллбэки можно редактировать и удалять, если, к примеру, при его создании вы в чём-то ошиблись.
Когда мы только начинаем изучать Python, мы закладываем некоторые вредные привычки при написании кода, о которых мы можем даже не подозревать.
Вы можете написать код, который сработает сейчас, но может не сработать в будущем, или вы можете использовать какие-то хитрые ходы вместо встроенной функции, которая могла бы облегчить вашу жизнь.
У большинства из нас сохранились не одна из тех вредных привычек при программировании на Python, что формируются в период первых месяцев обучения. Отличная новость в том, что вы можете с легкостью искоренить их, прочитав приведенный ниже текст.
1. Использование import *
Каждый раз, когда нам становится лень, то возникает соблазн импортировать все необходимое из модуля с помощью from xyz import *.
Это не самый лучший подход по многим причинам. Кот несколько из них:
Это может оказаться неэффективно: если в модуле очень много объектов, то вам придется долго ждать, пока все импортируется.
Это может вызвать конфликт имен переменных: когда вы используете *, то вы понятия не имеете, какие объекты вы импортируете и как они называются.
Как же с этим бороться? Импортируйте либо какой-то конкретный объект, либо весь модуль целиком.
# Using import *
# Bad
from math import *
print(floor(2.4))
print(ceil(2.4))
print(pi)
# Good
import math
from math import pi
print(math.floor(2.4))
print(math.ceil(2.4))
print(pi)
2. Try/except: отсутствие указания исключения в блоке «except»
Я очень долго пренебрегал этим. Сложно посчитать, сколько раз Pycharm давал мне понять (этими противными подчеркиваниями), что не нужно использовать «голое» исключение. Это идет в разрез с рекомендациями PEP8.
# Try - except
# Bad
try:
driver.find_element(...)
except:
print("Which exception?")
# Good
try:
driver.find_element(...)
except NoSuchElementException:
print("It's giving NoSuchElementException")
except ElementClickInterceptedException:
print("It's giving ElementClickInterceptedException")
Проблема «голых» исключений заключается в том, что оно будет перехватывать исключения SystemExit и KeyboardInterrupt, что затрудняет прерывание программы с помощью Control-C.
В следующий раз, когда вы будете использовать try/except, укажите исключение в блоке except.
3. Не использовать Numpy для математических вычислений
Очень часто мы забываем, что в Python есть множество пакетов, которые могут значительно облегчить нашу жизнь и сделать ее более продуктивной.
Одним из таких пакетов является Numpy – пакет для математических вычислений. Numpy может помочь вам вычислять математические операции быстрее, чем циклы for.
Допустим, что у нас есть массив random_scores, и мы хотим получить средний балл тех, кто не сдал экзамен (score>>dict_countries.keys()
dict_keys(['USA', 'UK', 'Canada'])>>>dict_countries.values()
dict_values([329.5, 67.2, 38])
Проблема тут заключается в том, что мы не всегда используем их должным образом.
Например, мы хотим просмотреть словарь и получить ключи. Вы можете использовать метод .keys, но знаете ли вы, что ключи можно получить, просто перебирая словарь? В этом случае использование метода .keys будет излишним.
# Not using .keys() properly
# Bad
for key in dict_countries.keys():
print(key)
# Good
for key in dict_countries:
print(key)
Кроме того, можно придумать некоторые хитрости для получения значений словаря, например, с помощью метода .items().
# Not using .items()
# Bad
for key in dict_countries:
print(dict_countries[key])
# Good
for key, value in dict_countries.items():
print(key)
print(value)
7. Никогда не использовать генераторы (или использовать их всегда)
Генератор предлагает более простой синтаксис при создании новой последовательности (списка, словаря и т.д.) на основе уже определенной последовательности.
Допустим, мы хотим перевести все элементы в нашем списке countries в нижний регистр.
И хотя вы могли бы это сделать просто с помощью цикла for, но также вы можете упростить работу при помощи генератора списка.
# Bad
countries = ['USA', 'UK', 'Canada']
lower_case = []
for country in countries:
lower_case.append(country.lower())
# Good (but don't overuse it!)
lower_case = [country.lower() for country in countries]
Генераторы – это очень полезно, но не злоупотребляйте ими! Помните правило Дзен Python: «Простое лучше, чем сложное».
8. Использование range(len())
Одни из первых функций, которые мы изучили будучи новичками – это range и len, поэтому не удивительно, почему многие люди имеют дурную привычку писать range(len()) при переборе списков.
Допустим у нас есть два списка: countries и populations. Если мы хотим пройтись по обоим спискам одновременно, то, вероятнее всего, вы воспользуетесь range(len()).
# Using range(len())
countries = ['USA', 'UK', 'Canada']
populations = [329.5, 67.2, 38]
# Bad
for i in range(len(countries)):
country = countries[i]
population = populations[i]
print(f'{country} has a population of {population} million people')
И хотя это в принципе выполняет свою работу, вы все равно можете упростить задачу, воспользовавшись enumerate (или, что еще лучше, воспользовавшись функцией zip для сопряжения элементов из обоих списков).
# OK
for i, country in enumerate(countries):
population = populations[i]
print(f'{country} has a population of {population} million people')
# Much Better
for country, population in zip(countries, populations):
print(f'{country} has a population of {population} million people')
9. Форматирование с помощью оператора +
Вероятно, одна из первых вещей, которую мы изучаем в Python, - это то, как соединять строки с помощью оператора +.
Это полезный, но не самый эффективный способ соединения строк в Python. Помимо этого, это не очень красиво – чем больше строк вам нужно соединить, тем больше операторов + вы будете использовать.
Вместо этого вы можете воспользоваться f-строкой.
# Formatting with + operator
# Bad
name = input("Introduce Name: ")
print("Good Morning, " + name + "!")
# Good
name = input("Introduce Name: ")
print(f'Good Morning, {name}')
Преимуществом f-строк в том, что они полезны не только для конкатенации, но и для других целей.
10. Использование изменяемых значений в качестве значений по умолчанию
Если вы включите изменяемое значение (например, список) в качестве параметра функции по умолчанию, то увидите нечто неожиданное.
# Bad
def my_function(i, my_list=[]):
my_list.append(i)
return my_list>>> my_function(1)
[1]
>>> my_function(2)
[1, 2]
>>> my_function(3)
[1, 2, 3]
В приведенном выше коде каждый раз, когда мы вызываем функцию my_function, список my_list сохраняет значения из предыдущих вызовов (а мы, скорее всего, хотим инициировать пустой список при каждом вызове функции).
Чтобы избежать такой проблемы, мы должны установить этот параметр my_list равным None и добавить условие if как показано ниже.
# Good
def my_function(i, my_list=None):
if my_list is None:
my_list = []
my_list.append(i)
return my_list>>> my_function(1)
[1]
>>> my_function(2)
[2]
>>> my_function(3)
[3]