Системное администрирование

индекс
199,95

Реализация отправки sms-уведомлений

В виду достаточно большого парка серверов/свитчей/модемов и иного активного оборудования в конторе, была установленная система мониторинга zabbix и успешно использовалась продолжительное время. Zabbix имеет замечательную возможность отправки уведомлений о возникших проблемах.
Для этого был написан скрипт отправки sms сообщений через шлюз email-to-sms оператора связи, ограничение по количеству смс с одного адреса в сутки было обойдено путем ротации исходящих адресов, работало более или мение сносно, но в последнее время смс сообщения через данный шлюз начали доходить с задержкой порядка 10-15 минут, что уже не очень нравилось.
Итак, было решено организовать отправку уведомлений через собственный GSM-терминал, порывшись в прайсах поставщиков и не обнаружив там подходящих по цене и характеристикам GSM модемов весьма огорчился.
И тут вспомнилось что дома валяется старый Siemens CX65 да еще и data-кабель к нему, после подключения телефона и курения доков по отправке sms сообщений пришел к не очень радостному выводу, оказывается siemens не поддерживает отправку sms в текстовом режиме, команда AT+CMGF=1 возвращает error.
Отправка сообщений в данных аппаратах возможна только в режиме PDU, ради спортивного интереса и для размятия мозгов было решено реализовать эту систему, был написан скрипт для перекодировки в PDU формат сообщений и отправки через телефон.

Мануал по системе отправки сообщений можно найти здесь: dreamfabric.com/sms/
Сам получившийся скрипт:
#!/usr/bin/python

import os
import sys
import time

def dectobin(i):
	b = ''
	while i > 0:
		j = i & 1
		b = str(j) + b
		i >>= 1
	return b

def SendSMS(dev,number,text):
	pdu_data = '00'
	pdu_data += '11' #SMS-SUBMIT
	pdu_data += '00' #TP-Message-Reference
	pdu_data += '0B' #Address-Length
	pdu_data += '91' #Address-Length
	'''Convert telephone number'''
	number += 'F'
	pdu_number = ''
	for i in range(0,len(number)):
		if i%2==0:
			continue
		pdu_number += number[i] + number[i-1]
	pdu_data += pdu_number
	pdu_data += '00' #TP-Protocol identifier
	pdu_data += '00' #TP-Data coding scheme
	pdu_data += 'AA' #TP-Validity-Period
	
	'''Convert text to binary format'''
	pdu_text_bin = []
	for i in text:
		dec_s=ord(i)
		if dec_s == 95:
			dec_s = 17
		if dec_s == 94:
			dec_s = 1
		if dec_s == 64:
			dec_s = 0
		if dec_s == 36:
			dec_s = 2
		if dec_s == 123:
			dec_s = 40
		if dec_s == 125:
			dec_s = 41
		if dec_s == 124:
			dec_s = 64
		if dec_s == 126:
			dec_s = 61
		if dec_s == 92:
			dec_s = 47
		if dec_s == 91:
			dec_s = 60
		if dec_s == 93:
			dec_s = 62
		bin = dectobin(dec_s)
		le = len(bin)
		while le<7:
			bin='0'+bin
			le = len(bin)		
		pdu_text_bin.append(bin)
	
	'''Encode binary to PDU format'''
	pdu_text_bin_cp = []
	n=0
	for i in range(0,len(text)):
		if (i>0) & ((i+1)%8==0):
			continue
		n+=1
		if n==8:
			n=1
		if i==len(text)-1:
			cp = pdu_text_bin[i][0:8-n]
		else:
			cp = str(pdu_text_bin[i+1][7-n:7] + pdu_text_bin[i])[0:8]
		pdu_text_bin_cp.append(cp)
			
	'''Convert PDU to hex'''
	pdu_text=''
	for i in pdu_text_bin_cp:
		hexi = str(hex(int(i,2)))[2:4].upper()
		if len(hexi) == 1:
			hexi = '0' + str(hexi)
		pdu_text += hexi
	
	'''Calculate text length'''
	len_hex = hex(len(text))[2:4].upper()
	if len(len_hex) == 1:
		len_hex = '0' + str(len_hex)
		
	'''Calculate PDU length'''
	pdu_data+=len_hex+pdu_text
	pdu_len = str(len(pdu_data)/2-1)
	
	if True:
		fd = os.open(dev, os.O_RDWR)
		os.write(fd, "AT+CMGF=0 \015")
		time.sleep(1)
		os.write(fd, "AT+CMGS=" + pdu_len + "\015")
		time.sleep(1)
		os.write(fd, pdu_data + "\032")
		os.close(fd)
	
def main(argv):
	SendSMS("/dev/ttyUSB0",argv[1],argv[2] + '\r\n' + argv[3])
	return 0

if __name__ == '__main__': main(sys.argv)

Не претендую на правильность кода, программированием на python занимаюсь не часто, поэтому любые оптимизации скрипта готов принять.

Телефон подключается при помощи data-кабеля, который представляет собой usb-serial переходник, основанный на чипе Prolific pl2303, данный чип стабильно работает в linux, никаких нареканий на работу связки телефон-комп нет.
Для корректной работы скрипта необходимо перед началом работы выставить нужные параметры ком-порта.
Для этого в /etc/udev/rules.d/50-udev.rules была добавлена следующая строчка:
KERNEL=="ttyUSB[0-9]", RUN+="/bin/stty -F /dev/%k speed 9600 -brkint -icrnl ixoff -imaxbel -opost -onlcr -isig -icanon -echo -echoe"
Теперь при каждом подключении кабеля параметры com-порта выставляются автоматически, нет необходимости запускать приложения вручную.
Далее в zabbix не сложная настройка и система отправки уведомлений готова, бюджетный вариант с GSM-терминалом работает гораздо лучше чем сервисы email-to-sms, плюс может отправлять уведомления о том что упал канал в инет, ранее после падения инета отправка соответственно не могла быть осуществлена.

Возможно данный материал будет кому либо полезен, старая мобилка наверняка валяется у каждого дома, а покупать gsm-модем стоймостью более 8000 рублей не очень хочется.
+38
27 апреля 2009, 11:39
115

комментарии (44)

0
pixelcube #
Дешевле же через какой-нибудь clickatell.com. не через email, а напрямую. не?
А телефон — не выбрасывайте, еще можно использовать как GPRS-модем.
0
GloooM #
Понятно что можно, но во первых это стоит денег, во вторых если пропадает инет то я об этом не узнаю )
+3
pixelcube #
SMS через телефон тоже стоит денег. А у сервиса — $0.027 ~ 90 коп. / сообщение
Тем более что на тестовый режим они дают 10 сообщений опробовать сервис.
Вариантов API выбирай на цвет и вкус: http(s) get/post, xml rpc/soap, smpp, smtp, dcom, даже ftp api

Про интернет. Думаю, раз уж вы так насчет SMS конкренто разобрались, то использовать сотик как модем и подавно.
+2
GloooM #
Смартс, смски по 10копеек )
0
Patron #
спасибо, искал такой сервис.
0
wire #
НЛО прилетело и опубликовало эту надпись здесь
+3
ZeX #
Я для этих целей использовал свою старую нокию и библиотеку mCore.
Очень удобно создавать и отправлять сообщение.

mCore.SMS objSMS = new mCore.SMS();

// Настройка подключения и проверка
// что подключение уже установлено
private void SendSms()
{
    if (!objSMS.IsConnected)
    {
      objSMS.Port = "COM4";
      objSMS.BaudRate = mCore.BaudRate.BaudRate_19200;
      objSMS.DataBits = mCore.DataBits.Eight;
      objSMS.Parity = mCore.Parity.None;
      objSMS.StopBits = mCore.StopBits.One;
      objSMS.FlowControl = mCore.FlowControl.None;
      objSMS.DisableCheckPIN = false;// chkDisableCheckPIN.Checked;
      objSMS.Encoding = mCore.Encoding.Unicode_16Bit;
    }
    string strSendResult = objSMS.SendSMS("+7921XXXXXXX", "MS SQL сервер упал!", false);
}


* This source code was highlighted with Source Code Highlighter.


Поддерживает кучу мобильных телефонов, и довольно много всяких интересных функций, таких как USSD запросы, получение и чтение входящих SMS и другое.

Единственный минус, конечно, что она платная. Зато есть триальная версия. Ограничение триала в том, что ко всем SMS'кам будет дописывать строчка внизу, что SMS отправлено с помощью этой библиотеки.

0
unicast #
А ещё вместо отправки email'а можно сделать скрипт типа wget -O /dev/null sms_.../sendsms.php?login=123&pass=123&message=text
Почти у всех смс-провайдеров есть такая штука.
+2
GloooM #
Угу, а еще попросить юзеров ввести капчу =)
0
unicast #
Если у вас платный аккаунт у смс-провайдера, то капчу не надо — я же указал в качестве параметра логин и пароль.
Ведь смс через телефон тоже не бесплатная.
0
GloooM #
Смс через телефон стоит 10 копеек, и работает даже когда инет пропадает.
Я прекрасно понимаю что есть куча сервисов, но отправка через мобилу уже реализована и работает понадежнее сервисов.
–2
null #
Вы бы тогда сразу подписали внизу статьи: «Никакие альтернативные реализации в этом топике не принимаются».
0
darkk #
Пока все альтернативы имели меньшую функциональность ;-)
0
Unkn0wn #
Обожаю такие топики, когда в комментариях предлагают еще десяток своих вариантов решения вопроса.
Посоветуйте способ организовать отправку смс через телефон на виндах, что то типа www.lissyara.su/?id=1787
0
GloooM #
Кстати интересный вариант по ссылке, а он отправляет через PDU?
0
Unkn0wn #
Не в курсе, только бегло просмотрел, так как он для никсов.
0
EVEN #
да очень просто, покупаешь Siemens TC35i Terminal 3 500р + антенна 800р. Подключаешь к com порта а дальше вообще всё просто, даже через CMD можно к немо обращаться.

Вот так у меня он в ребут уходит

echo at^^smso > com4

а так звонит

echo atd0887; > com4
0
Unkn0wn #
Записал себе как вариант. Небольшое уточнение: он подключается именно через ком порт? Не USB?
0
EVEN #
да, простой COM порт, USB не покупай, стоит 4 промышленных com модема и проблем нету, а у USB могут быть всякие зависания.
–1
VDG #
делаем
0
Unkn0wn #
Что делаете?
–1
VDG #
отправку смс через телефон на виндах
0
Unkn0wn #
Вы не многословны. Может посвятите в детали? Кто Вы такие, как именно делаете, какие условия, цены?
–1
VDG #
вот будет готово, тогда и расскажу. черкните мне в личку, чтобы Ваш контакт у меня остался. как будет релиз, я Вам отпишусь.
0
ivanday #
'/usr/bin/printf $NOTIFICATIONTYPE$\n\nService | /usr/local/bin/scmxx --device /dev/ttyU0 --number $CONTACTPAGER$ --send --sms --direct — > /var/log/scmxx.log 2>&1'
вот такое у нас стоит в Nagios. Отправляет sms через какой-то старенький Siemens. посредством утилиты scmxx
0
norguhtar #
Вообще если вы посмотрите, в zabbix есть поддержка отправки уведомлений, но она умеет работать только с теми телефонами что позволяют отправлять sms без PDU.
0
GloooM #
Именно об этом и заметка, отправка текстом не сложна в настройке.
0
Unkn0wn #
Кто что знает про www.visualgsm.com? При беглом осмотре есть бесплатная версия, я только не нашел в чем ее триальность заклчается.
0
Stazz #
GPRS/EDGE-модемы, которые сейчас предлагают многие операторы мобильной связи по 2000-3000тр, имеют возможность отправки СМС. Возможно, что с таким девайсом систему оповещения сожно реализовать проще и без перекодирования в PDU.
0
EVEN #
Novacom GNS-300RS — 2500р, нет?
0
MazaFakagro #
Kannel наше всё
0
sunnybear #
будущее здесь? Компьютеры будут общаться с нами? Echelon Conspiracy :)
0
expolit #
Я купил ком модем с gprs за 65$, откуда вы взяли 8к, не понятно, это было год назад.
0
expolit #
Сорри, температура, немного ступил, использовал я его как раз для получения и отправки смс. Дёшево и сердито.
+1
Ferroman #
Хех я вот pymobile.sourceforge.net/ использовал.
0
GloooM #
О, спасибо за подсказку, сам что-то не нашел этого проекта.
0
Ferroman #
Его реально трудно найти, я надыбал одно сообщение на каком-то испанском форуме, проверил — подошло.
0
FanKiLL #
А в чём прикол смс? Просто смс у меня ассоциируется с MTV. Через push какой нибудь себе на мыло уведомления нельзя сделать?
0
Arceny #
Можно использовать какой-нибудь модем от Билайн.Интернет Дома
0
Denisio #
ага, а покажи две классические трудоемкие добавки (можно во второй части):
1) русские буквы
2) concatenated messages
:)
0
GloooM #
Да, это былобы интересно, но пока совершенно нет необходимости, хотя при наличии свободного времени можно заняться)
0
SaveTheRbtz #
В своё время делал отправку СМС на основе SprutNet (Описание в PDF)
Цена вопроса 2500р, в комплекте антена.
Умеет GPRS, так что если кто что накосячил в настройках роутера можно через него зайти (правда это тоже настраивать надо)
0
Abadd0N #
Извиняюсь, я конечно не гуру программирования, но объясните, зачем это условие? %)
if True:
fd = os.open(dev, os.O_RDWR)
. . .

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