Индикация работы режима DnD на BLF клавише в Asterisk

    image
    DnD достаточно востребованная функция, но обычно режим включается на самом телефоне, не уведомляя об этом Asterisk, отчего тот будет обращаться к телефону пользователя, думая, что тот на месте и готов ответить на звонок. Как нам включить режим DnD на самом Asterisk и чтобы кнопка включения при активированном DnD моргала красным цветом?
    Для этого нам потребуется телефон с BLF кнопками и пара макросов. Проверялось на IP телефонах Grandstream GXP серии, самых разных. Сервером выступает Linux c Elastix, ну и можно просто Asterisk 1.6+.

    Внимание! На некоторых телефонах требуется обновление прошивки для корректной работы BLF клавиш.

    1. Создаем макросы в /etc/asterisk/extensions_override_freepbx.conf. Он конечно подключен в extensions.conf.
    Текст макросов:

    [ext-dnd-hints]
    exten => *761000,1,Goto(app-dnd-toggle,*76,1)
    exten => *761000,hint,Custom:DEVDND1000
    


    В этом макросе прописаны номера телефонов которые нужно отслеживать, в примере указан extension 1000. *76 это feature code.
    По аналогии нужно создать записи для каждого номера, которому нужна функция DnD.

    [app-dnd-toggle]
    include => app-dnd-toggle-custom
    
    exten => *76,1,Answer
    exten => *76,n,Wait(1)
    exten => *76,n,Macro(user-callerid,)
    exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate)
    exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES)
    exten => *76,n,Set(STATE=RINGING)
    exten => *76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => *76,n,Playback(do-not-disturb&activated)
    exten => *76,n,Macro(hangupcall,)
    exten => *76,n(deactivate),dbDel(DND/${AMPUSER})
    exten => *76,n,Set(STATE=NOT_INUSE)
    exten => *76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => *76,n,Playback(do-not-disturb&de-activated)
    exten => *76,n,Macro(hangupcall,)
    exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE})
    exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)})
    exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return)
    exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)})
    exten => sstate,n,Set(ITER=1)
    exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE})
    exten => sstate,n,Set(ITER=$[${ITER} + 1])
    exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin)
    exten => sstate,n(return),Return()
    


    Это сам макрос переключающий состояния, тут ничего менять не требуется.

    2. Включаем ext-dnd-hints в нужным нам контекст, например:

    [from-internal]
    include => ext-dnd-hints
    exten => h,1,Hangup
    


    Тут аккуратнее, нужно указать все контексты, которые входят в from-internal, иначе они перестанут работать.

    3. Настраиваем на телефоне клавишу: прописываем на ней номер *761000 и включаем режим BLF. Если режим BLF не работает, читаем текст курсивом в начале топика.

    4. В CLI делаем dialplan reload и проверяем появился ли наш хинт. В нормальном режиме вид будет такой:

    xtelekom*CLI> core show hint *761000
                    *761000@ext-dnd-hints       : Custom:DEVDND1000     State:Idle            Watchers  1
    


    Если телефон не запрашивает состояние DnD, то Watchers будет равно 0.

    Некоторые телефоны при недоступной BLF (моргающей красным цветом) при вызове добавляют еще ** к номеру, в таком случае номер получается вида ***761000. Для работы такого варианта макрос немного другой, помещу его под спойлер, потому что он повторяет первый макрос:
    Еще макрос
    [ext-dnd-hints]
    exten => *761000,1,Goto(app-dnd-toggle,*76,1)
    exten => ***761000,1,Goto(app-dnd-toggle,***76,1)
    exten => *761000,hint,Custom:DEVDND1000
    
    [app-dnd-toggle]
    include => app-dnd-toggle-custom
    
    exten => *76,1,Answer
    exten => *76,n,Wait(1)
    exten => *76,n,Macro(user-callerid,)
    exten => *76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate)
    exten => *76,n(activate),Set(DB(DND/${AMPUSER})=YES)
    exten => *76,n,Set(STATE=RINGING)
    exten => *76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => *76,n,Playback(do-not-disturb&activated)
    exten => *76,n,Macro(hangupcall,)
    exten => *76,n(deactivate),dbDel(DND/${AMPUSER})
    exten => *76,n,Set(STATE=NOT_INUSE)
    exten => *76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => *76,n,Playback(do-not-disturb&de-activated)
    exten => *76,n,Macro(hangupcall,)
    exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE})
    exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)})
    exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return)
    exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)})
    exten => sstate,n,Set(ITER=1)
    exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE})
    exten => sstate,n,Set(ITER=$[${ITER} + 1])
    exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin)
    exten => sstate,n(return),Return()
    
    exten => ***76,1,Answer
    exten => ***76,n,Wait(1)
    exten => ***76,n,Macro(user-callerid,)
    exten => ***76,n,GotoIf($["${DB(DND/${AMPUSER})}" = ""]?activate:deactivate)
    exten => ***76,n(activate),Set(DB(DND/${AMPUSER})=YES)
    exten => ***76,n,Set(STATE=)
    exten => ***76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => ***76,n,Playback(do-not-disturb&activated)
    exten => ***76,n,Macro(hangupcall,)
    exten => ***76,n(deactivate),dbDel(DND/${AMPUSER})
    exten => ***76,n,Set(STATE=UNAVAILABLE)
    exten => ***76,n,Gosub(app-dnd-toggle,sstate,1)
    exten => ***76,n,Playback(do-not-disturb&de-activated)
    exten => ***76,n,Macro(hangupcall,)
    exten => sstate,1,Set(DEVICE_STATE(Custom:DND${AMPUSER})=${STATE})
    exten => sstate,n,Set(DEVICES=${DB(AMPUSER/${AMPUSER}/device)})
    exten => sstate,n,GotoIf($["${DEVICES}" = "" ]?return)
    exten => sstate,n,Set(LOOPCNT=${FIELDQTY(DEVICES,&)})
    exten => sstate,n,Set(ITER=1)
    exten => sstate,n(begin),Set(DEVICE_STATE(Custom:DEVDND${CUT(DEVICES,&,${ITER})})=${STATE})
    exten => sstate,n,Set(ITER=$[${ITER} + 1])
    exten => sstate,n,GotoIf($[${ITER} <= ${LOOPCNT}]?begin)
    exten => sstate,n(return),Return()
    



    В следующий раз расскажу как делать наблюдение за состоянием в очереди таким же образом.

    P.S. Иногда на grandstream требуется перезагрузка телефона, иначе кнопка не работает корректно.
    Поделиться публикацией
    Комментарии 1

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое