- призначення системи правити
- компоненти системи правити
- Збір і аналіз статистики правити
- система повідомлень правити
- Підготовка бази mysql правити
- Підготовка плану набору Asterisk правити
- Скрипт обробки балансу правити
Наша взаимовыгодная связь https://banwar.org/
приклад звітів
УВАГА! ДОКУМЕНТ У РОЗРОБКИ
призначення системи
правити
Використовується для роботи IP телефонії Asterisk спільно с3G модемами в якості каналів голосової стільникового зв'язку. Завдання системи, запитувати баланс по СІМ-карт операторів стільникового зв'язку і аналізувати їх відповідь. Отриману інформацію зберігати в базі даних. На підставі даних з бази будувати звіти про рух коштів на рахунках і організації повідомлень, в разі якщо баланс виявиться нижче порогового значення. Модеми, баланс яких нижче допустимого рівня, повинні автоматично виключатися з роботи.
компоненти системи
правити
Перевірено на ubuntu server 10.04 LTS
- Asterisk (сервер голосового зв'язку)
- chan_dongle (модуль для asterisk забезпечення голосових дзвінків через 3G модеми)
- mysql для зберігання і обробки даних
- openssl для обчислення md5 значень унікальності рядків
- apache або будь-який інший web сервер (не обов'язково, потрібен для зручності перегляду звітів)
Збір і аналіз статистики
правити
Перший скрипт призначений на періодичне виконання (раз в 30 хвилин) в cron, здійснює USSD запити з додаванням випадкової складової часу від 0 до 65 секунд з моменту запуску для кожного модему. Це потрібно для того, щоб уникнути одночасного надсилання запитів відразу з усіх пристроїв.
Asterisk повинен бути попередньо налаштований на те, щоб забезпечувати відправку і отримання USSD запитів через модеми.
Відповідь операторів Asterisk поміщає в текстовий файл, а скрипт виконує вилучення інформації про баланс з цих відповідей, спираючись на рядок розбору (парсинга), яка може бути написана для кожного оператора індивідуально. У поточному скрипті описано для МТС (2 варіанти), Білайну і Мегафона для Хабаровського краю. Можливо в інших регіонах доведеться щось міняти. Прошу свої варіанти додавайте в коментарях.
Кожен рядок при внесенні в базу контролюється на унікальність по md5 в якості індексу. Таким чином не грає ролі скільки разів запускається скрипт і зчитує файл відповідей, в базу будуть внесені тільки унікальні значення і повторного додавання не відбудеться.
При виконанні скрипт не чекає, коли кожен оператор відповість про стан балансу, а відразу будує звіти з попередніх даних. Таким чином поточний стан балансу потрапить до звіту тільки після наступного запуску.
система повідомлень
правити
Другий скрипт призначений для повідомлення користувача про закінчення балансу на рахунках операторів. Він виконується раз на добу, зчитує підсумкові значення балансу з бази. Далі перевіряється, чи не опустилися значення балансу нижче встановленого порогу для одного і більше операторів, і якщо це виявилося, на електронну пошту відправляється лист з цим списком. Поштова підсистема MTA повинна бути налаштована в системі.
Підготовка бази mysql
правити
Створюємо нову таблицю gsmbalans в базі asteriskcdrdb. Вона зазвичай вже є, якщо встановлено FreePBX. Але можна створити і свою.
- Заходимо в консоль mysql
- Виконуємо запит на створення нової таблиці gsmbalans в базі asteriskcdrdb
Додамо користувача сервера mysql gsmbalans з паролем gSmBlNs
GRANT usage ON *. * TO gsmbalans @ localhost IDENTIFIED BY 'gSmBlNs'; GRANT ALL privileges ON gsmbalans. * TO gsmbalans @ localhost; Підготовка плану набору Asterisk
правити
Для успішної роботи файл з відповідями повинен мати певний формат.
nano /etc/asterisk/extension_custom.confДодамо в діалплан роботу з ussd запитами в контекст прописаний в dongle.conf
[From-gsm] exten => ussd, 1, Verbose (Incoming USSD: $ {BASE64_DECODE ($ {USSD_BASE64})}) exten => ussd, n, System (echo '$ {STRFTIME ($ {EPOCH} ,,% d.% m.% Y% H:% M:% S)} - USSD - $ {DONGLENAME}: $ {BASE64_DECODE ($ {USSD_BASE64})} '>> / var / www / msg) exten => ussd, n, Hangup ()Приклад файлу з відповідями операторів на запит балансу
28.04.2012 4:30:21 - USSD - 000104: 216.4 p. 28.04.2012 4:30:29 - USSD - 000105: Баланс 393.08 р. iPhone в офісах Білайн від 16 590 р. Інф 068006 28.04.2012 4:30:34 - USSD - 000106: Balans: 14,20r Скрипт обробки балансу
правити
nano / etc / balans Скопіюємо і вставимо
#! / Bin / bash # Файл відповідей оператора opermsg = / var / www / msg # Число зчитувальних останніх рядків з файлу # (при первинному заповненні бази ставимо велике значення) # Процедура розбору великої кількості рядків може займати # тривалий час, так- як потрібно обчислювати md5 # для кожного рядка tn = 1 # Ім'я бази даних dbname = asteriskcdrdb # Ім'я таблиці балансу tbname = gsmbalans # Ім'я користувача бази dbuser = gsmbalans # Пароль користувача бази dbpass = gSmBlNs # Мінімальний баланс при досягненні якого, модем відключається з роботи . min_bal = 50 # відключати модеми, баланс яких нижче порогового otklmod = yes # Шлях до папки зі звітами (каталог web сервера) repath = / var / www / bal # Створюємо індексний сторінку в каталозі веб сервера # Намагатися створити папку автоматично? mkdir -p $ repath echo "<b> Баланс модемів </ b> <br>"> $ repath / index.htm echo "<a href='balans_ob.txt'> Зведений баланс </a> <br>"> > $ repath / index.htm echo "<b> Детально </ b> <br>" >> $ repath / index.htm # Список модемів і відповідних їм типів відповідей операторів # про стан балансу # заповнення: # 1. Номер Dongle пристрої, 2. Префікс рядка розбору, 3. Номер сімки # 4. Ім'я оператора 5. USSD запит балансу # Увага, прогалини в полях не допускаються for opsos in \ "000103 MTS2 +79140000001 МТС * 100 #" \ "000101 MTS + 79140000002 МТС * 100 # "\" 000106 MTS +79140000003 МТС * 100 # "\" 000104 MGF +79240000004 Мегафон * 100 # "\" 000102 MGF +79240000005 Мегафон * 100 # "\" 000105 BEE +79620000006 БИЛАЙН * 102 # " \ "000107 BEE +79090000007 БИЛАЙН * 102 #" do num = `echo $ opsos | awk '{print $ 1}' `oper =` echo $ opsos | awk '{print $ 2}' `numsim =` echo $ opsos | awk '{print $ 3}' `fovsim =` echo $ opsos | awk '{print $ 4}' `ussdzap =` echo $ opsos | awk '{print $ 5}' `## Включаємо модеми (вони можуть бути відключені при низькому балансі) перед запитом. asterisk -rx "dongle start $ num" let D = $ RANDOM / 1000 && sleep $ D && asterisk -rx "dongle ussd $ num $ ussdzap" & # Створюємо звіти по зняттю / Поповненню коштів з сімкарт echo "Оператор зв'язку $ fovsim" > $ repath / bal- $ num .txt echo "Федеральний номер СІМ карти $ numsim" >> $ repath / bal- $ num .txt mysql -u $ dbuser -p $ dbpass -D $ dbname -e "\ set @a = 0,0; select port as 'Модем', time as 'Дата Час', balans as 'Баланс', if (delta> 0 and balans <> delta, delta, '-') as 'Прихід', if (delta <0 , delta, '-') as 'Витрата' \ from (select * from (select port, time, balans, round (balans-pv_balans, 2) as delta \ from (select port, time, @ a as pv_balans, @ a : = balans, balans \ from $ {tbname} where port = '$ {num}' order by time) as t1) as t2 where delta <> 0) as t3; " | column -t >> $ repath / bal- $ num .txt # Наповнюємо індексний сторінку echo "<a href='bal- $num .txt'> $ num </a> $ numsim $ fovsim <br>" >> $ repath / index.htm balans = "" ######## Варіанти парсинга балансу для різних операторів ####################### # Результат розбору повинен бути у вигляді: # 28.04.2012 08: 30: 17; 52.70; 000101 ################################# ############################################### # Оператор МТС if [ "$ {oper}" = "MTS"] then cat $ opermsg | grep $ num | grep USSD | grep Balans | sed -E 's / (- |: Balans: | r) /; / g' | sed 's /,/./ g' | awk -F ";" '{Print $ 1 ";" $ 4 ";" $ 3}' | tail -n $ tn >> tmpallbalans fi # Оператор МТС варіант 2 if [ "$ {oper}" = "MTS2"] then cat $ opermsg | grep $ num | grep USSD | grep Баланс: | sed -E 's / (- |: Баланс: | р | р.) /; / g' | sed 's /,/./ g' | awk -F ";" '{Print $ 1 ";" $ 4 ";" $ 3}' | tail -n $ tn >> tmpallbalans fi # Оператор БИЛАЙН if [ "$ {oper}" = "BEE"] then cat $ opermsg | grep $ num | grep USSD | grep Баланс | grep р. | sed -E 's / (- |: Баланс | р.) /; / g' | sed 's /,/./ g' | awk -F ";" '{Print $ 1 ";" $ 4 ";" $ 3}' | tail -n $ tn >> tmpallbalans fi # Оператор Мегафон if [ "$ {oper}" = "MGF"] then cat $ opermsg | grep $ num | grep USSD | grep p. | sed -E 's / (- |: | p.) /; / g' | awk -F ";" '{Print $ 1 ";" $ 4 ";" $ 3}' | tail -n $ tn >> tmpallbalans fi # Універсальний парсер. Використовувати тільки в тестових цілях. if [ "$ {oper}" = "UNV"] then cat $ opermsg | grep $ num | grep USSD | sed 's / ^ /; / g' | grep -o -P ". + (? = - USSD -) | (- USSD - \ w + (? = \ :)) | ([- 0-9] + ([.,] \ d +)?)" | sed 's / $ /; / g' | tr "\ n" "_" | sed 's /; _; / \ n / g' | sed -r 's / (_ | - USSD -) // g' | sed 's /,/./ g' | awk -F ";" '{Print $ 1 ";" $ 2 ";" $ 3}' | grep -P -v "(; $ | ^;)" | awk -F ";" '{Print $ 1 ";" $ 3 ";" $ 2}' | tail -n $ tn >> tmpallbalans fi ######################################### ####################################### done # Парс через підрядник файл, і вважаємо md5 для кожної рядки cat tmpallbalans | while read line; do mdha = `echo" $ line "| openssl md5` baldate = `echo" $ line "| awk -F ";" '{Print $ 1}' | awk '{print $ 1 "." $ 2}' | awk -F "." '{Print $ 3 "-" $ 2 "-" $ 1 "" $ 4}' `balance =` echo "$ line" | awk -F ";" '{Print $ 2}' `modnumr =` echo "$ line" | awk -F ";" '{Print $ 3}' '# Заповнюємо базу значеннями mysql -u $ dbuser -p $ dbpass -D $ dbname -e "INSERT INTO $ {tbname} (md5, port, balans, time) values (' $ mdha ',' $ modnumr ',' $ balance ',' $ baldate '); " > / Dev / null # Відключаємо модеми з низьким балансом celbal = `echo $ balance | awk -F "." '{Print $ 1}' `if [" $ {celbal} "-le" $ min_bal "] then if [" $ {otklmod} "=" yes "] then sleep 60 && asterisk -rx" dongle stop now $ modnumr " fi fi done # Створюємо зведений звіт по поточних балансів zapr = "select port as 'Модем', balans as 'Баланс', time as 'Дата Час' \ from (select * from (select max (time) as last_date, port as prt \ from $ {tbname} group by port) as tbl1 \ JOIN $ {tbname} where tbl1.last_date = $ {tbname} .time and tbl1.prt = $ {tbname} .port) as itog where port <> '' order by port; " mysql -u $ dbuser -p $ dbpass -D $ dbname -e "$ {zapr}" | column -t> $ repath / balans_ob.txt # Очищення тимчасових файлів echo ""> tmpbalans echo ""> tmpallbalans
Робимо скрипт виконуваним
Додаємо його виконання в крон на кожні півгодини
echo "* / 30 * * * * root / etc / balans> /tmp/bal.tmp" >> / etc / crontab- Перед налаштуванням повідомлень, необхідно налаштувати поштову підсистему на пересилку пошти, якщо це ще не зроблено. пересилання пошти
Створимо скрипт, який буде отримувати з бази поточний стан балансів і в разі досягнення мінімального значення одного або більше пристроїв, повідомляти про це по електронній пошті
nano / etc / balansevent # установки для перегляду базі dbname = asteriskcdrdb tbname = gsmbalans dbuser = gsmbalans dbpass = gSmBlNs # Поріг спрацьовування при значенні менше якого буде надіслано повідомлення porog = 100 # Адреса одержувача повідомлення (декілька адрес через кому без пробілів maddr = user @ mail.com # Створюємо зведений звіт за низькими балансам zapr = "select port as 'Модем', balans as 'Баланс', time as 'Дата Час' \ from (select * from (select max (time) as last_date, port as prt \ from $ {tbname} group by port) as tbl1 \ JOIN $ {tbname} where tbl1.last_date = $ {tbname} .time and tbl1.prt = $ {tbname} .port) as itog where port <> '' and balans < '$ {porog}' order by port; "mysql -u $ dbuser -p $ dbpass -D $ dbname -e" $ {zapr} "| column -t> emltmp nbal =` cat emltmp | wc -l ` if [1 -le $ {nbal}] then cat emltmp | mail -s 'Small Balans Events' $ maddr fiЗробимо скрипт виконуваним і додамо в крон для запуску раз на добу о 6 годині ранку
chmod + x / etc / balansevent echo "0 6 * * * root / etc / balansevent> / dev / null" >> / etc / crontabUSSD -) | (- USSD - \ w + (? = \ :)) | ([- 0-9] + ([.,] \ d +)?