Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 3747 сообщений
Cообщения с меткой

sms - Самое интересное в блогах

Следующие 30  »
rss_rss_hh_new

Собственный «Кто звонил?» на базе Мультифона

Воскресенье, 06 Марта 2016 г. 07:23 (ссылка)

На какие вопросы вы найдёте ответы в этой статье:




  • как отправлять USSD через GSM/3G/4G-модем и читать ответы;

  • как отправлять SMS через Мультифон;

  • как использовать Яндекс SpeechKit в автоответчике на Asterisk.



На какие вопросы вы не найдёте ответов:




  • зачем нужен собственный «Кто звонил?».



Все понимают механизм сервиса, аналогичного «Кто звонил?»: по недоступности звонок уходит на специальный номер, там его принимают, сообщают звонящему, что абонент недоступен, и отправляют абоненту СМС с информацией о звонке. В приёме звонка с Мультифона на Астериске никаких тонкостей нет.



Вкратце
Регистрация:



register => 79xxxxxxxxx@multifon.ru::79xxxxxxxxx@sbc.megafon.ru/79xxxxxxxxx


Транк:



[multifon](!)
type=peer
insecure=port,invite
host=sbc.megafon.ru
fromdomain=multifon.ru
context=from_multifon
dtmfmode=inband

[multifon-in](multifon)

; Если мы ещё и звонить хотим
[multifon-out](multifon)
defaultuser=79xxxxxxxxx
fromuser=79xxxxxxxxx
secret=




Первый вопрос, который встал передо мной в полный рост…



Как отправить СМС?



Самый простой путь, конечно же, купить человеческий HTTP API у какого-нибудь гейта и задёшево отправлять через него. Но во-первых, это неспротивно. А во-вторых, у меня на тарифе несколько сотен СМС включено в абонплату, и с телефона я их почти не отправляю.

Перепробовав все возможные варианты с MessageSend (и через диалплан, и через АМИ, и через чёрта лысого), а также помурыжив SipSak, я сдался и попробовал скрипт для Yate.

О чудо! СМС через Мультифон отправляются.

Но Yate – слишком тяжеловесный движок, подумал я. Yate должен крутиться демоном и требует совершенно избыточной для этих задач конфигурации, подумал я. Поэтому, изучив перловый скрипт, я вычленил из него главное и вернулся к сипсаку. Главным оказался набор нестандартных заголовков (включая обязательного совершенно определённого юзер-агента, ага):



User-Agent: MCPC-MG-1-0-34-3490/2.0.0.5301
X-Movial-Content: sms/text
X-Movial-DeliveryReport: true
Content-Type: text/plain; charset=ISO-10646-UCS-2


Кстати, кастомный юзер-агент, насколько я понимаю, изначально полностью исключал возможность отправки через Астериск.

На первый взгляд, всё казалось просто. Но сообщения всё равно не уходили. Включив дебаг у сипсака, я понял, что эта скотина имеет набор предопределённых заголовков, которые тупо дублируются, если заданы в командной строке. Пришлось брать в руки напильник.

Обработав сипсак так, чтобы кастомные заголовки он считал приоритетными, а дубли отбрасывал, я добился наконец первого результата. Но моя радость была бы неполной, если бы сипсак корректно кодировал передаваемое сообщение. Расписывать всю эпопею вкостыливания в код, построенный на нуль-терминированных строках, UCS2-BE я не буду, сразу представлю на ваш суд результаты своих трудов: https://github.com/wolandtel/sipsak. Сам процесс отправки СМС я обернул в удобный скрипт. Для комплекта в последнем репозитории есть скрипт settings.sh, который упрощает настройку пароля и маршрутизации (SIP, GSM+SIP, GSM) на мультифоне.

Ну, вот, отправлять СМС мы умеем. Теперь можно настроить сам…



Автоответчик



Здесь нам поможет AGI. Скажу сразу, что от природной лени протокол AGI реализовывать я не стал, а лишь сделал в скрипте такую эмуляцию, которая позволяет выполнить задачу. А именно, скрипт должен дождаться от астериска ответа на команду STREAM FILE, чтобы проигрывание не закончилось раньше времени.



Диалплан
; autoresponder
exten => 79xxxxxxxxx,1,NoOp
same => n,AGI(notify.agi)
same => n,Set(MSG="Абонент умер. Когда воскреснет, может перезвонить. Но хотите ли Вы этого?")
same => n,Answer
; Params: speaker, emotion, robot
; speaker: [мужские]: zahar, ermil; [женские]: jane, omazh.
; emotion: good, neutral, evil, mixed.
; robot: true, false.
same => n,AGI(tts.agi,${MSG},ermil,neutral,true)
same => n,Hangup




Можно было, конечно, отправлять СМС из того же скрипта, которым проигрывается сообщение, но с точки зрения структуры приложения логично было их разнести.



notify.agi
#!/bin/bash

while read line; do
[ -z "$line" ] && break
num=$(echo $line | grep 'agi_callerid: ' | sed 's/agi_callerid: //')
[ -n "$num" ] && break
done < /dev/stdin

[ -z "$num" ] && exit 1

/usr/local/multifon/sms.sh 79xxxxxxxxx "Пропущенный вызов [$(date '+%Y-%m-%d %H:%M:%S')] с номера +$num"




Абсолютно никакого AGI, по факту. Просто делаем, что требуется, и закругляемся.



tts.agi
#!/bin/bash

text="$1"
speaker="$2"
emotion="$3"
robot="$4"

key=
dir=/var/lib/asterisk/tts
url=https://tts.voicetech.yandex.net/generate
dbg=${0/.agi/.log}

fname="$dir/$(echo -n "$text-$speaker-$emotion-$robot" | md5sum | cut -d' ' -f1)"
wav="${fname}.wav"

echo -e "$@" > "$dbg"
while read line; do
echo $line >> "$dbg"
[ -z "$line" ] && break
done < /dev/stdin

[ -f "$wav" ] || /usr/bin/curl -s --data-urlencode "text=$text" \
--data-urlencode format=wav \
--data-urlencode lang=ru-RU \
--data-urlencode "speaker=$speaker" \
--data-urlencode "key=$key" \
--data-urlencode "emotion=$emotion" \
--data-urlencode "robot=$robot" \
"$url" > "$wav" || exit 1

for f in al ul gsm; do
[ -f "${fname}.$f" ] || /usr/bin/sox "$wav" -r8k "${fname}.$f" || exit 2
done

echo -e "STREAM FILE $fname 0"

read line < /dev/stdin
echo $line >> "$dbg"




Здесь тоже нет AGI. Мы только дожидаемся ответа от Астериска командой read, чтобы не закрыться раньше, чем он проиграет сообщение. Прошу обратить внимание на параметр -r8k для сокса. Почему-то без параметров он неправильно выставляет рейт выходному файлу, и сообщение получается замедленным в два раза. Подробности самого Яндекс SpeechKit API и то, как получить ключ, есть в документации.



Основная часть на этом закончена. Но статья будет неполной без описания нюансов.



Подготовка сим-карты



Очевидно, чтобы всё это завелось, потребуется отдельный номер с Мультифоном. Вы покупаете сим-карту и…? Простой и очевидный путь – вставить её в телефон, набрать необходимые запросы и начать использовать. Но мы не ищем лёгких путей. У меня с давних времён валяется пачка 3G-модемов (знаменитый E1550 и чуть менее знаменитые E150), но нет ни одного свободного телефона. А использовать свой для таких операций я не люблю: лишний раз выключать, вскрывать.

Итак, для получения и отправки СМС мы будем использовать давно и хорошо всем известный smstools. Настройку я описывать не буду, ибо боян. Только автодекодинг не включайте. А то будет вам мусор вместо тела сообщения.

Итак, после приобретения сим-карты нужно сделать две вещи:




  • получить пароль для личного кабинета (ибо эти бабуины убили Сервис-гид, и теперь для каждого номера требуется собственный логин);

  • подключить Мультифон (ибо эти бабуины сломали веб-интерфейс, и без USSD не обойтись).



И если с приёмом СМС всё понятно, то USSD – не такая прозрачная вещь.

Перед тем, как продолжить, можете ознакомиться с [репозиторием|(https://github.com/wolandtel/smstools) дополнений к smstools, облегчающих работу с SMS и USSD. В разделе example репозитория есть перловый инструмент работы с USSD, который я использовал для понимания сути кодирования/декодирования символов в USSD. Авторство не указано, и ссылок нет потому, что я не помню, где его взял. Можно использовать его, но лично я не понимаю perl, а техномагию я не люблю. Поэтому чтобы почувствовать контроль над ситуацией я написал утилиты encode и decode. Как мне кажется, код на си куда проще для понимания, поэтому утилиты будут полезны тем, кто тоже захочет знаний.

Подозреваю, что если выставить другую кодировку командой AT+CSCS, проблема отпадёт сама собой, но мы же не ищем…

В остальном работа с USSD проста: модем регистрирует три девайса ttyUSB. Пишем в первый, читаем из последнего.

Для подключения личного кабинета достаточно просто отправить 105: ./ussd.sh '*105#' (подразумевается, что /dev/modem указывает на первый из ttyUSB модема). Дожидаемся СМС с паролем (удобнее всего это делать командой ls -lrt /var/spool/incoming), после чего смотрим ./viewsms .

Мультифон подключается в два этапа: запустив cat /dev/ttyUSB2, отправляем *137#. Копируем ответ и выясняем, что там написано, с помощью decode. А приходит в ответ менюшка, где для подключения нужно выбрать пункт 1. Выполняем ./ussd 1 и получаем в СМС пароль.



На этом можно было бы и завершить, но так как мы имеем дело с бабуинами, стоит упомянуть про…



Организационные моменты




  1. Обязательно укажите, чтобы новую сим-карту подключили на существующий лицевой счёт. Насколько я понял, отключение по неактивности не работает, если на все номера один баланс. Да и вообще удобнее. Когда был жив сервис-гид с возможностью управлять всеми номерами из-под одной учётной записи, этот совет был ещё актуальнее.

  2. В современном мире наебизнеса уже никому не надо объяснять, что сразу после покупки сим-карты необходимо отключать все условно-бесплатные опции (в том числе, «Кто звонил?», ага). Но! Бабуины пошли дальше и некоторые из условно-бесплатных опций не отображаются в личном кабинете. Отключить их можно только звонком в контакт-центр. Желательно подробно прочитать описание тарифа, чтобы выяснить, каких же замечательных вещей вам впарилипродали.

  3. В качестве номера для отправки СМС я использую свой основной номер, потому что на нём есть предоплаченный пакет. Естественно, для этого Мультифон на нём тоже должен быть включен (но совершенно не обязательно держать его постоянно зарегистрированным). Дополнительный номер используется только для приёма звонков.



PS



К сожалению, Мультифон не передаёт номер, переадресовавший звонок. Поэтому, если вы хотите подключить свой бонусный «Кто звонил?» друзьям/родным, придётся на каждого человека покупать отдельный номер под автоответчик. Ещё можно попробовать переадресацию с доп. набором (+79XXXXXXXXXpXX), но я не проверял. Если проверите, пишите.



А вот теперь – всё!





Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/278679/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
anykey13

Без заголовка

Понедельник, 29 Февраля 2016 г. 08:37 (ссылка)
youreklama.ru/prikolnye-sms...?_utl_t=li

Прикольные SMS - Интересные факты новости статьи


1456724236_kopiy (700x700, 119Kb)

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
vsemmoney

SMS рассылки любого объёма и тематики - Купля/продажа и услуги - Форум о заработке в интернете и инвестициях

Вторник, 12 Января 2016 г. 19:28 (ссылка)
vsemmoney.ru/topic/1623-sms...-tematiki/


SMS рассылки любого объёма и тематики - отправлено в Купля/продажа и услуги: Любые смс рассылки в любых объёмах



Оптимальный сро...

Комментарии (0)КомментироватьВ цитатник или сообщество
ru_prnews

Sms2gsm снизил стоимость сообщения до полкопейки

Четверг, 24 Декабря 2015 г. 18:10 (ссылка)


Сервис по рассылке сообщений Sms2gsm выпустил новое приложение для ПК. Его функционал позволяет осуществлять рассылку с большинства популярных гаджетов: телефонов, планшетофонов или модемов.


 




Приложение ориентировано на клиентов, заинтересованных в том, чтобы сделать рассылку сообщений дешевле и удобнее. Дружелюбный интерфейс и простота использования программы от Sms2gsm выделяют ее среди подобных решений. СМС рассылка организована максимально удобно: клиенту нужно подготовить лишь список номеров в формате Excel и создать текст письма.



Стоимость одного сообщения составит всего 0,5 копеек благодаря использованию специальных тарифов, предполагающих месячную абонентскую плату в 180 рублей. Для сравнения, при использовании онлайн-сервисов стоимость одного SMS составит 1,5 рубля. Программа от Sms2gsm способна существенно сэкономить средства пользователей в долгосрочной перспективе. Стоимость приложения составляет 6000 рублей. Это единоразовое вложение, позволяющее сократить расходы на рассылку в несколько раз.



Единственным ограничением является то, что программа не может выполнить подмену номера или каким-либо образом подписать его. При получении СМС клиент будет видеть номер SIM-карты, с которой осуществлялась рассылка.





Особое внимание создатели программы уделили безопасности: приложение работает даже без интернет-подключения. Соответственно, нет необходимости в том, чтобы загружать базу номеров на сторонние сайты для организации рассылки.



Таким образом, использование программы предполагает всестороннюю защиту пользовательских данных, существенную финансовую экономию и полную автоматизацию процесса рассылки.



Контакты:



mail@sms2gsm.ru

http://www.sms2gsm.ru


Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Оповещения Zabbix через sms используя GSM модем. Простая настройка

Понедельник, 09 Ноября 2015 г. 16:21 (ссылка)





Zabbix сервер — это хорошо. Правильно настроенный, он мониторит серваки и необходимые мне узлы. В случае проблем на них он с радостью уведомляет меня по электронной почте. Не так давно выяснилось, что оба наших любимых провайдера (основной и резервный интернет каналы) решили не обеспечивать ИБП свое сетевое оборудование в здании. Поэтому когда вырубают электричество (а бывает такое!) Zabbix бы и рад разбудить веселым письмом, а никак! В общем, решил заморочиться уведомлением по sms. Именно через GSM модем чтобы не было зависимости от интернета.



Поискав по интернету варианты отправки sms Zabbix-ом, нашел варианты решения, но они показались мне длинными. Поэтому сделал по своему «на коленке». Постараюсь подробно описать не сложное рабочее решение и «грабли».



И так что у меня было:




  1. Zabbix 2.4 на OC Debian 7 — мониторит несколько серваков, к одному из них подключен через USB кабель APC smart ups 3000. Мониторинг состояния UPS настроен по этой статье.

  2. GSM модем Huawei e1550 (Мегафон) который валялся дома со времен отсутствия проводного интернета. Как показала практика — вставив в уже настроенную систему другой модем Huawei все так же работает, не требуя перенастройки!



Для отправки из терминала sms я использовал gnokii.



Поехали:



# apt-get install gnokii
Вставляем GSM модем в сервак и проверяем:

# lsusb


Среди прочего видим что-то типа:



Bus 001 Device 009: ID 12d1:14ac Huawei Technologies Co., Ltd.




Проверяем определился ли как модем:



# ls /dev/ttyUSB*


Если пусто (а меня было пусто):



# apt-get install usb-modeswitch


Вытаскиваем и заново вставляем модем.



Проверяем определился ли:



# ls /dev/ttyUSB*


Видим что-то типа:



/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2




Осталось чуть-чуть до первой отправки sms!



Создаем конфиг gnokii. Я положил его в /home



# nano /home/user/sms.conf


Текст конфига
[global]
port = /dev/ttyUSB0
model = AT
initlength = default
connection = serial
use_locking = no
serial_baudrate = 115200




Сохраняем и тестируем:



# echo "text" | gnokii --config /home/user/sms.conf --sendsms +7ХХХХХХХХХХ


(+7ХХХХХХХХХХ — тут, конечно, номер, на который надо отправить)



Должна прийти sms без проблем. Обо всем этом есть много инструкций на просторах интернета и до этого момента проблем у меня не возникло.



Дальше важно!



Заббикс в системе работает от пользователя zabbix. Разрешаем ему использовать модем.



# nano /etc/group


dialout:x:20:zabbix




Иначе при отправке от этого пользователя получим что-то типа:



GNOKII Version 0.6.30

Gnokii serial_open: open: Permission denied

Couldn't open ATBUS device: Permission denied

Telephone interface init failed: Command failed.

Quitting.

Command failed.




Еще при отправке встречал ошибку:



Cannot open logfile ./gnokii-errors

WARNING: cannot open logfile, logs will be directed to stderr




Это значит не нашлось файла по пути:



~/.cache/gnokii/gnokii-errors




Изменяем разрешения для пользователя использовать sudo без пароля:



# nano /etc/sudoers


zabbix  ALL=(ALL) NOPASSWD: /usr/bin/gnokii




Дальше логинимся под пользователем zabbix и пишем очень простой скрипт.



# nano /home/user/smsscript


Текст скрипта
#!/bin/sh
zabbixesmsto=$1
zabbixsubject=$2
echo "$zabbixsubject" | /usr/bin/sudo /usr/bin/gnokii --config /home/user/sms.conf --sendsms "$zabbixesmsto"


Сохраняем. Именно /usr/bin/sudo и /usr/bin/gnokii — для меня это оказалось важно!

Не забываем от рута сделать:

chmod +x /home/user/smsscript
Проверяем работу скрипта:

/home/user/smsscript +7XXXXXXXXXX test


Если пришла sms — все практически готово! Осталось прикрутить к Zabbix-у. Если не пришла, то проверяем, все ли сделали так как написано выше.



Я создавал скрипт для заббикса в /home/user/ потому что в конфиге zabbix_server.conf написно: AlertScriptsPath=/home/user/



Если у вас не так, то либо меняем расположение скрипта, либо изменяем в конфиге путь на /home/user/ — не забыть рестаратнуть zabbix server!



В интерфейсе заббикса идем в Администрирование — Способы оповещений.



Создать способ оповещения.



image



Затем настраиваем оповещение для вашего пользователя в заббиксе. Администрирование — Пользователи.



image



И Настройка — Действия.



image



Действие я сделал отдельное, чтобы sms приходили не по каждому поводу, а только при срабатывании определеных триггеров. Так как при отпавке в sms пишется только тема, то в само сообщение нет смысла что-то писать. А в условие добавил:



image



Вот и все! Дернул из разетки ИПБ и через несколько минут получил гневное sms от заббикса! Теперь он меня везде достанет, зараза!



P.S.: Так как электричество отключают не часто, то и расходов на sms совсем мало.


Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/270497/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Бюджетная рассылка СМС

Суббота, 07 Ноября 2015 г. 20:07 (ссылка)

Приветствую всех хаброжителей!



Конечно, зализанная тема про рассылку смс сообщений, но как говориться: «много — не мало». Как-то так получилось, что именно она меня постоянно преследует: то одни, то другие добрые люди попросят принять участие (советом, например) в реализации бюджетной рассылки сообщений. И поэтому чтобы не пропадать накопленному добру, оставлю здесь, а вдруг кому-то пригодится…





Итак-с… Опускаем все варианты реализации на базе обычного компа и оси семейства NT. А перейдем сразу к «автономным» системам.



Чем может похвастаться arduino в этом направлении? Отвечу сразу, ОНО работает, но есть нюансы, о которых напишу ниже. Вообщем, имеем китайский вариант arduino 2560 (было перепробовано практически вся линейка) и два дополнительных модуля — сеть W5100 (наиболее стабильный вариант) и GSM SIM 900. Выглядит это все дело как-то так.



image



Задача была следующая:

— устройство должно уметь общаться по http

— отправлять сообщение

— выдавать результат в формате json



Гугл делится всей необходимой информацией, и на выходе получаем следующий код:



Скетч
#include 
#include

#include

#include "SIM900.h"
#include
#include "sms.h"

#include
#include

byte mac[] = { 0x90, 0xA2, 0x00, 0x00, 0x00, 0x01 };
IPAddress ip(192,168,34,139);

EthernetServer server(80);

char char_in = 0;
String HTTP_req;

SMSGSM sms;

boolean started=false;
bool power = false;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {

Serial.begin(9600);

lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("INIT GSM...");
lcd.setCursor(0,1);
lcd.print("WAIT!!!");

//powerUp();
gsm.forceON();

if (gsm.begin(4800)) {
Serial.println("\nstatus=READY");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("READY");
started=true;
}
else {
Serial.println("\nstatus=IDLE");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("IDLE");
}

Ethernet.begin(mac, ip);
server.begin();

}

void software_reset() {
asm volatile (" jmp 0");
}

void loop() {
EthernetClient client = server.available();

if (client) {
while (client.connected()) {
if (client.available()) {
char_in = client.read(); //
HTTP_req += char_in;

if (char_in == '\n') {

Serial.println(HTTP_req);

if(HTTP_req.indexOf("GET /res") >= 0) {
reset_processing(&HTTP_req, &client);
break;
}

if(HTTP_req.indexOf("GET /sms") >= 0) {
sms_processing(&HTTP_req, &client);
break;
}

if(HTTP_req.indexOf("GET /test") >= 0) {
test_processing(&HTTP_req, &client);
break;
}
else {
client_header(&client);
break;
}
}
}
}
HTTP_req = "";
client.stop();
}

if(power) {
delay(1000);
software_reset();
}
}

char* string2char(String command) {
if(command.length()!=0){
char *p = const_cast(command.c_str());
return p;
}
}

void parse_data(String *data) {
data->replace("GET /sms/","");
data->replace("GET /test/", "");

int lastPost = data->indexOf("\r");
*data = data->substring(0, lastPost);
data->replace(" HTTP/1.1", "");
data->replace(" HTTP/1.0", "");
data->trim();
}

// explode
String request_value(String *data, char separator, int index) {
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data->length()-1;

for(int i=0; i<=maxIndex && found<=index; i++) {
if(data->charAt(i)==separator || i==maxIndex) {
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data->substring(strIndex[0], strIndex[1]) : "";
}

bool gsm_status() {
bool result = false;
switch(gsm.CheckRegistration()) {
case 1:
result = true;
break;
default:
break;
}
return result;
}

bool gsm_send(char *number_str, char *message_str) {
bool result = false;
switch(sms.SendSMS(number_str, message_str)) {
case 1:
result = true;
break;
default:
break;
}
return result;
}

void reset_processing(String *data, EthernetClient *cl) {
client_header(cl);
cl->println("\{\"error\": 0, \"message\": \"restarting...\"\}");

power = true;
}

void test_processing(String *data, EthernetClient *cl) {
parse_data(data);

if(started) {
client_header(cl);
cl->println("\{\"id\":" + request_value(data, '/',0) + ",\"error\":0" + ",\"message\":\"test success\"\}");
}
}

void sms_processing(String *data, EthernetClient *cl) {
parse_data(data);

if(started) {
if (gsm_send(string2char(request_value(data, '/', 1)), string2char(request_value(data, '/', 2)))) {
client_header(cl);
cl->println("\{\"id\":" + request_value(data, '/',0) + ",\"error\":0" + ",\"message\":\"success\"\}");
}
else {
if(!gsm_status()) {
client_header(cl);
cl->println("\{\"id\":" + request_value(data, '/',0) + ",\"error\":2" + ",\"message\":\"gsm not registered\"\}");
power = true;
}
else {
client_header(cl);
cl->println("\{\"id\":" + request_value(data, '/',0) + ",\"error\":1" + ",\"message\":\"fail\"\}");
}
}
}
}

void client_header(EthernetClient *cl) {
cl->println("HTTP/1.1 200 OK");
cl->println("Content-Type: text/plain");
cl->println("Connection: close");
cl->println();
}






Заливаем, упаковываем в коробочку. Вроде бы выглядит красиво, отдаем добрым людям.



image



Что получилось в коде:

— подняли простенький http

— обрабатываем простые GET

— отправляем полученные данные через SERIAL на SIM 900

— отвечаем с помощью «JSON»



И вот тут есть один большой нюанс, перед умными людьми стоит задача реализовать какой-нибудь сервис, чтобы научиться отправлять через это устройство сразу пачку сообщений, но это уже не мои проблемы. В производстве устройство себя повело удовлетворительно.



Наращиваем мощности… Задача полностью аналогичная: повторение — мать учения. Умные люди уже создали классный сервис для работы с предыдущим устройством: очередь, история и прочие полезности.



Итак, на руках имеем raspberry pi, такой же модуль SIM 900 (был взят только ради экспериментов, потому что линукс прекрасно работает с 3g-модемами через USB) и сам 3g-modem huawei e-линейки



image



Снова задаем гуглу нужные вопросы, читаем результаты, определяемся с языком реализации — python — быстро, просто, надежно…



скрипт
import serial, time
from flask import Flask
import RPi.GPIO as GPIO

app = Flask(__name__)


def sim900_on():
gsm = serial.Serial('/dev/ttyAMA0', 115200, timeout=1)
gsm.write('ATZ\r')
time.sleep(0.05)

abort_after = 5
start = time.time()
output = ""

while True:
output = output + gsm.readline()
if 'OK' in output:
gsm.close()
return True
delta = time.time() - start
if delta >= abort_after:
gsm.close()
break


#GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.output(11, True)
time.sleep(1.2)
GPIO.output(11, False)
return False


def gsm_send(id, port, phone, msg):

delay = False
if 'AMA' in port:
delay = True


msg = msg.replace('\\n', '\n')
msg = msg.replace('\s', ' ')

gsm = serial.Serial('/dev/tty%s' % port, 115200, timeout=1)
gsm.write('ATZ\r')

if delay:
time.sleep(0.05)

gsm.write('AT+CMGF=1\r\n')

if delay:
time.sleep(0.05)

gsm.write('AT+CMGS="%s"\r\n' % phone)

if delay:
time.sleep(0.05)

gsm.write(msg + '\r\n')

if delay:
time.sleep(0.05)

gsm.write(chr(26))

if delay:
time.sleep(0.05)

abort_after = 15
start = time.time()
output = ""

while True:

output = output + gsm.readline()
#print output
if '+CMGS:' in output:
print output
gsm.close()
return '{"id":%s,"error":0,"message":"success", "raw":"%s"}' % (id, output)
if 'ERROR' in output:
print output
gsm.close()
return '{"id":%s,"error":0,"message":"fail", "raw":"%s"}' % (id, output)

delta = time.time() - start
if delta >= abort_after:
gsm.close()
return '{"id":%s,"error":1,"message":"timeout", "raw":"%s"}' % (id, output)

@app.route('/sms////',methods=['GET'])
def get_data(id, port, phone, msg):
return gsm_send(id, port, phone, msg)

@app.route('/',methods=['GET'])
def index():
return "Hello World"

if __name__ == "__main__":
sim900_on()
app.run(host="0.0.0.0", port=8080, threaded=True)






Скармливаем питону, запускаем с помощью «start-stop-daemon», придаем дружелюбный вид, отдаем добрым людям…



image



Получилось практически один в один, только за счет шины USB систему можно расширять. В производстве претензий вообще не оказалось — все были ОЧЕНЬ довольны.



Устройство получилось настолько удачным, что появилось желание использовать это дело в «личных» интересах, а именно внедрить в систему мониторинга данный аппарат. Но надо было избавиться от главного нюанса — отсутствие очереди сообщений. Принцип реализации я взял у одного известного вендора (он предлагал программно-аппаратный комлекс, часть которого поднимала smtp-сервер для обработки уведомлений и отправки ее на gsm-устройство). Такая схема встраивается в любую систему мониторинга.



Итак, нужные знания уже давно получены, приступаем к реализации.



SMTP-демон
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import smtpd
import asyncore
import email
import MySQLdb
import subprocess

def InsertNewMessage(phone, msg):
conn = MySQLdb.connect(host="localhost", # your host, usually localhost
user="sms", # your username
passwd="sms", # your password
db="sms") # name of the data base
c = conn.cursor()
c.execute('insert into message_queue (phone, message) values ("%s", "%s")' % (phone, msg))
conn.commit()
conn.close()

class CustomSMTPServer(smtpd.SMTPServer):

def process_message(self, peer, mailfrom, rcpttos, data):

msg = email.message_from_string(data)
phone = rcpttos[0].split('@',1)[0]
addr = mailfrom

for part in msg.walk():
if part.get_content_type() == "text/plain": # ignore attachments/html
body = part.get_payload(decode=True)


InsertNewMessage(phone, str(body))

subprocess.Popen("/home/pi/daemons/sms/pygsmd.py", shell=True)

server = CustomSMTPServer(('0.0.0.0', 25), None)

asyncore.loop()






Демонизация происходит, как я уже писал выше, с помощью «start-stop-daemon», а сам smtp скрипт запускает подпроцесс для работы с базой сообщений.



gsm скрипт
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import serial
import time
import MySQLdb
import commands


def gsm_send(port, phone, msg):

print 'Sending message: %s to: %s' % (msg, phone)
gsm = serial.Serial('/dev/tty%s' % port,
460800,
timeout=5,
xonxoff = False,
rtscts = False,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE )
gsm.write('ATZ\r\n')
time.sleep(0.05)
gsm.write('AT+CMGF=1\r\n')
time.sleep(0.05)
gsm.write('''AT+CMGS="''' + phone + '''"\r''')
time.sleep(0.05)
gsm.write(msg + '\r\n')
time.sleep(0.05)
gsm.write(chr(26))
time.sleep(0.05)

abort_after = 15
start = time.time()
output = ""


while True:

output = output + gsm.readline()
#print output
if '+CMGS:' in output:
#print output
gsm.close()
return 0
if 'ERROR' in output:
#print output
gsm.close()
return 1

delta = time.time() - start
if delta >= abort_after:
gsm.close()
return 1

def msg_delete(list):
conn = MySQLdb.connect(host="localhost",
user="sms",
passwd="sms",
db="sms")
c = conn.cursor()
c.execute("delete from message_queue where id in %s;" % list)
conn.commit()
conn.close()

def msg_hadle():
list = tuple()
conn = MySQLdb.connect(host="localhost",
user="sms",
passwd="sms",
db="sms")
c = conn.cursor()
c.execute("select * from message_queue")

numrows = int(c.rowcount)
if numrows > 0:
for row in c.fetchall():
result = gsm_send('USB0', ('+' + row[1]), row[2])
if result == 0:
list +=(str(row[0]),)

conn.close()

if len(list) == 1:
qlist = str(list).replace(',','')

if len(list) > 1:
qlist = str(list)

if len(list) > 0:
msg_delete(qlist)

del list

while True:
try:
msg_hadle()
except:
print "mysql error"

time.sleep(10)






В связке с моей системой мониторинга устройство ведет себя адекватно, хотя работает не так давно. Надеюсь, материал будет полезен кому-нибудь.



Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/261387/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Кохагед

Освободить фундамент

Среда, 21 Октября 2015 г. 08:12 (ссылка)

Продолжу о том, как все начиналось: http://www.liveinternet.ru/users/kohaged/post372546221

25 числа я весь день металась, как оборотень во время превращения. Я то сидела и улыбалась, то ревела. Впервые за долгие годы я почувствовала, что мне нужен какой-то другой человек. Не Катя. Я не знала, что с этим делать. Или знала слишком много вариантов. Мне было больно и счастливо. Мысль, что уже в пятницу я увижу Тая снова, перекрывала все, и это было максимально показательно. А ближе к вечеру между нами и вовсе произошел вот такой sms-диалог:
- А ведь в пятницу вечером везде будет до фига народу.Это весьма печально. (16.07)
- это да. но я хотел предложить погулять, если будет более-менее тепло, а, например, в сокольниках подальше от центра народу не особенно много даже в выходные. а еще я свободен и завтра, так же вечером8) (18.29)
- Хочу встретиться завтра.И хочу пойти с тобой еще в одно кафе.Четверг ведь.И вот в пятницу будет теплее,а завтра около нуля. (18.38)
- давай! там же, в то же время? (18.42)
- Yep (18.46)
И я не могла уже думать ни о чем другом. Хотя надо было.
Когда Катя пришла вечером, у меня не было никакого решения. Я не планировала ничего говорить. Это была наша дата, 9 лет совместной жизни. Мы ели пиццу и смотрели кино. Я рассказала Кате про Тая, и мне казалось, что я рассказала достаточно нейтрально - так, как о любом очень приятном знакомом. Но, наверное, нет.
Мы легли спать.
Я, как вчера, помню эти минуты, хотя с них прошло почти 7 месяцев. Мы уже пожелали друг другу спокойной ночи. Я лежала и пыталась уснуть. И Катя позвала меня. Я могла промолчать. Сделать вид, что уже сплю. Она позвала меня несколько раз. Она уже замолчала. И все же я откликнулась. Я откуда-то знала, про что она хочет сказать, но все равно откликнулась. А она откуда-то знала, какой будет мой ответ, и на мой отклик сказала, мол, не важно. И это был второй шанс промолчать. Но я не умею молчать. И, снова немного полежав в тишине, я переспросила ее, в чем дело. Она тоже выдержала паузу. А потом спросила: "Что ты испытываешь к этому человеку?". Следующая пауза была, наверное, вечной. Я полежала. Потом села. И сказала: 'Я не знаю.". Я не знала.
И этого было достаточно.
Была целая ночь слез, криков и молчания. По той же инерции, по которой мне казалось, что я ничего не чувствую в Таю, теперь мне казалось, что я все еще влюблена в Катю, все еще хочу быть с ней, и она мне все еще нужна. Столько лет это все было правдой. Мой мозг не мог так быстро осознать обратное.
Поэтому я умоляла ее не уходить от меня. Я сказала, что Тай мне нужен, и я ничего не могу с этим поделать. Я говорила, что мне необходимо хоть немного времени, чтобы разобраться в своих чувствах. Катя была категорична: расставание, абсолютное, все. Я сказала, что раз она прогоняет меня, я на несколько дней уеду в Щелково и дам ей подумать. Она сказала, что не о чем думать, но я цеплялась за любой шанс. Я не представляла, что все обернется наоборот..
Мир стремительно уходил из-под ног, а я не понимала, почему не чувствую этого. Почему не падаю, когда вся моя огромная жизнь рушится. Как-то ближе к утру я уснула. Утром проснулась первая, проводила Катю на работу, она не сказала мне и трех слов. И весь день моей превалирующей эмоцией было недоумение. Я недоумевала, почему я так спокойна, почему не катаюсь по полу в истерике, когда рассталась с человеком, с которым жила 9 лет. Я даже думала, что у меня некий шок. Даже медитировать пыталась, чтобы проснуться.
Но мы-то с вами в нашем настоящем знаем, где собака зарыта. Мне было грустно из-за того, что я причинила боль тому, кто так долго был мне дорог. Я переживала за свое благополучие и опасалась перемен. Но не хуже того. Я ждала встречи с Таем, мечтала о ней, и она была главной для меня. Я не знала, нужна ли я ему вообще, что он думает про наше общение, что чувствует ко мне. Но я знала, что совсем скоро мы будем говорить и касаться друг друга. Это стоило 9 лет, 90 лет, и сколько бы у меня ни было, я бы отдала их..

Метки:   Комментарии (9)КомментироватьВ цитатник или сообщество

Следующие 30  »

<sms - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda