Main

Отправка уведомлений с помощью SMS

(Windows-версия)

На данной странице рассмотрим пример использования канала GSM для организации уведомлений с помощью sms из системы MajorDoMo.

Что нам понадобиться: Любой GSM Модем марки "Huawei" (использовался E173)

Программа "GSM-Modem Controller" (страница программы с описанием возможностей http://serj.kz/content/3)

Далее рассмотрим пример использования sms уведомлений из системы.

Сделаем сценарий запроса текущего баланса.

 include_once(ROOT.'lib/hardware/smsgw.php');
 $res=sendUSD("*100#", "Parol");
 if (preg_match('/(\d+,\d+)/is',$res,$m)) {
  $balance=floatval(str_replace(",",".",$m[1]));
  sg('ThisComputer.Balance', $balance);
 }
say("Баланс ".round(gg("ThisComputer.Balance"))." рублей");

На данном примере мы запросили текущий баланс и записали значение в переменную ThisComputer.Balance

(USSD запрос, пароль и переменную меняем на свои)

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

Класс Timer, объект ClockChime , метод ' 'onNewMinute можно прописать запрос баланса например раз в день в вечернее время

if (timeIs('22:00')) {
runScript('Balans');
}

результат выведем в меню.

Далее рассмотрим пример SMS уведомления при превышении температуры котла более 70 градусов.

Напишем сценарий следующего плана.

 include_once(ROOT.'lib/hardware/smsgw.php');
 $data="Температура котла: ".gg("wireTemp0.temp");
 $res=sendSMS("+7953546546546",$data, "Parol");

цифры и пароль меняем на свои

Далее приведен пример кода для отправки sms если температура котла превысила 70 °С

$t=$this->getProperty('temp');
$d=$this->getProperty('direction');

if ($t>=70) {
 if (((round($t)/5)==round(round($t)/5) && $d!=0) || ($t>70)) { //
  if ($d>0) {
   say('Температура котла поднялась до '.$t.' градусов');
   runScript('sendSMS');
  } else {
   say('Температура котла снизилась до '.$t.' градусов');
   runScript('sendSMS');
  }
 }
}

В итоге мы получили возможность получать уведомления о любых изменениях в системе. Реализация зависит только от Вашей фантазии.

 UPD: Есть возможность отправлять бесплатные SMS через сервис sms.ru

1. Регистрируемся на сайте.

2. Заходим в раздел "Программистам" и видим там пример отправки sms уже с вашим API key

3. В MDM делаем например такой сценарий

$data=gg("tempOutdoor.temp");
getUrl("http://sms.ru/sms/send?api_id=ХХХХХХХХХХХХХto=7917ХХХХХХХ&text=Температура:$data");

В результате получаем СМС с запрошенной температурой.

 
 

Обсуждение

 

sergejey: Обсуждение страницы Отправка уведомлений с помощью SMS

Panchez: Добрый день! Не могу разобраться с превышением температуры из данной темы, при превышении ничего не происходит, свойства объекта изменяются а метод не выполняется.

sergejey: А как именно проиходит установка температуры? Если свойство меняется, а метод не вызывается, значит не хватает вызова этого метода.

Panchez: Установка происходит из 1wire датчика - объект.temp, метод класса tempChanged //$params $old_temp=$this->getProperty('temp'); $t=round($params*2)/2; $this->setProperty('temp',$t); if ($t>$old_temp) { $d=1; } elseif ($t<$old_temp) { $d=-1; } else { $d=0; } $this->setProperty('direction',$d); $this->setProperty("updated",time()); $this->setProperty("updatedTime",date("H:i",time()));

sergejey: Надо тогда добавить ещё вызов метода в код, который выполняется при обновлении значения 1-wire: callMethod("объект.tempChanged"); Т.е. получается, что связанное свойство обновляется, но метод сам по себе не вызовется -- его нужно вызвать принудительно.

Panchez: Надо тогда добавить ещё вызов метода в код, который выполняется при обновлении значения 1-wire: callMethod("объект.tempChanged"); Т.е. получается, что связанное свойство обновляется, но метод сам по себе не вызовется -- его нужно вызвать принудительно. Так не получилось. В поле temp постоянно 0. Посмотрел по форуму, нашел аналогичную тему про "Слежение за температурой контура отопления", уже обсуждалась подобная проблема. Этот вызов заработал if ($params) { callMethod('SensorZal.tempChanged',array('t'=>$params)); }

dmw: На Linux Ubuntu Server как настроить модуль? wvdial нужен?

dmw: Сдалал чтобы можно было отправлять SMS и USD с сервера Ubuntu аналогично как и в примере выше: Для отправки SMS нужно чтоб был установлен пакет Gnokii. Для отправки USSD и получения результата идет обращение напрямую к модему AT-командами. В принципе и SMS отправлять через AT-команды можно и тогда никакое сторонее ПО не нужно, но в Gnokii есть очень интересная утилитка - демон smsd, которая постоянно запущена и служит для приема входящих sms, сохранении их в базу, т.е. сервер можно заставить отвечать на SMS-ки, более подробно про smsd здесь. Своего демона писать пока сил и мозгов не хватает, поэтому оставил пока так. Может можно подобное на MDM собрать? Вот так немного подкорректировал /lib/hardware/smsgw.php: <?php /** * Title * * Description * * @access public */ function sendSMS($phone, $text, $pass_server='000000') { $phone=preg_replace('/^\+/', '', $phone); if (substr(php_uname(), 0, 7) == "Windows") { $address = gethostbyname ('127.0.0.1'); //IP Ђ¤аҐб ў иҐЈ® Є®¬ЇмовҐа  $service_port=8000; //Џ®ав //$pass_server='000000'; //Џ а®«м $socket = socket_create (AF_INET, SOCK_STREAM, 0); if ($socket < 0) { echo "socket create failed reason: " . socket_strerror ($socket) . "\n"; } $result = socket_connect ($socket, $address, $service_port); if ($result < 0) { echo "socket connect failed.\nReason: ($result) " . socket_strerror($result) . "\n"; } $text = iconv("UTF-8","Windows-1251",$text); $in = base64_encode($pass_server."#SENDSMS#[TYPE]0[NUMBER]".$phone."[TEXT]".$text); //ЏаЁ¬Ґа ®вЇа ўЄЁ б¬б //$in = base64_encode($pass_server."#CMD#[USSD]*102#"); //ЏаЁ¬Ґа § Їа®б  USSD Є®¬ ­¤л $out = ''; socket_write ($socket, $in, strlen ($in)); //echo "Response:\n\n"; $res=''; while ($out = socket_read ($socket, 2048)) { $res.=$out; } socket_close ($socket); $res = iconv("Windows-1251","UTF-8",$res); } else { $comand = 'LANG=ru_RU.utf8; echo "'.$text.'" | gnokii --sendsms +'.$phone; $res = shell_exec($comand); } return $res; } function sendUSD($text, $pass_server='000000') { $phone=preg_replace('/^\+/', '', $text); if (substr(php_uname(), 0, 7) == "Windows") { $address = gethostbyname ('127.0.0.1'); //IP Ђ¤аҐб ў иҐЈ® Є®¬ЇмовҐа  $service_port=8000; //Џ®ав //$pass_server='000000'; //Џ а®«м $socket = socket_create (AF_INET, SOCK_STREAM, 0); if ($socket < 0) { echo "socket create failed reason: " . socket_strerror ($socket) . "\n"; } $result = socket_connect ($socket, $address, $service_port); if ($result < 0) { echo "socket connect failed.\nReason: ($result) " . socket_strerror($result) . "\n"; } $text = iconv("UTF-8","Windows-1251",$text); $in = base64_encode($pass_server."#CMD#[USSD]".$text); //ЏаЁ¬Ґа ®вЇа ўЄЁ б¬б //$in = base64_encode($pass_server."#CMD#[USSD]*102#"); //ЏаЁ¬Ґа § Їа®б  USSD Є®¬ ­¤л $out = ''; socket_write ($socket, $in, strlen ($in)); //echo "Response:\n\n"; $res=''; while ($out = socket_read ($socket, 2048)) { $res.=$out; } socket_close ($socket); $res = iconv("Windows-1251","UTF-8",$res); if (preg_match('/USSD-RESPONSE\[.+?\]:(.+)/is', $res, $m)) { $res=$m[1]; } } else { $port = "/dev/ttyUSB0"; //указать куда смонтировался модем $f = fopen ($port, "rw+"); //Чтобы послать USSD запрос на номер *100#, команда должна выглядеть так: //AT+CUSD=1,"AA180C3602",15 (двойные кавычки обязательны) $text = "AT+CUSD=1,\"".encodePDU($phone)."\",15\r\n"; fputs($f, $text); while ($s = fgets($f)) { if (substr($s, 0, 5) == "+CUSD") { $codetext = substr(trim($s), 10, -4); $res = decodePDU($codetext); if (strpos($res, "1 - Dalee") !== false) { fputs($f, "AT+CUSD=1,".encodePDU("1").",15\r\n"); } else break; } } fclose($f); } return $res; } function decodePDU($in) { $command = "echo ".$in." | perl -ne '@a = m/([0-9A-F]{4})/g; map { eval \"print \\\"\\\\x{\$_}\\\"\"; } @a;' 2>/dev/null"; $out = shell_exec ($command); return $out; } function encodePDU($in) { $out = ""; for ($i = 0; $i < (strlen($in)-1); $i++) { $t = $i%8+1; if ($t == 8) continue; $c = ord($in[$i])>>($i%8); $oc = $c; $b = ord($in[$i+1]) & ((1 << $t)-1); $c = ($b << (8-$t)) | $c; $out .= strtoupper(str_pad(dechex($c), 2, '0', STR_PAD_LEFT)); } return $out; } ?> И вот тут закралась засада, скрипт MDM указанный в статье ничего не возвращает. Если создать отдельный скрипт для запроса баланса balans.php в корне сайта и запустить из браузера www.адрес сайта/balans.php, то тоже белый лист: <?php $ROOT = '/var/www/'; include_once($ROOT.'lib/hardware/smsgw.php'); $res=sendUSD("*100#", "Parol"); if (preg_match('/(\d+,\d+)/is',$res,$m)) { $balance=floatval(str_replace(",",".",$m[1])); echo $balance; } ?> А если запустить из консоли: php balans.php то все работает отлично. Такое подозрение что MDM не дает исполнять shell_exec(), либо в настройках где запрещено, либо прав не хватает? Сергей, можете помочь разобраться?

sergejey: видимо, так настроены права, что веб-сервер (от имени которого выполняется скрипт) не может запускать команды через shell_exec. как вариант, использовать safe_exec для этих целей -- он не выдаст результат назад, но команда будет передана основному циклу, который обычно запускается от имени пользователя с правами по-лучше чем веб-сервер.

dmw: Да, с правами проблема была. Используемому ПО потребовалось:chmod a+s /usr/bin/perl chmod a+s /usr/bin/gnokii и добавил в crontab при автозагрузке chmod 777 для модема (иначе права к устройству слетают после перемонтирования/перезагрузки): chmod 777 /dev/ttyUSB0и все заработало. Может кто знает как chmod выполнять после монтирования USB-устройтва?

Amarok: Обсуждение страницы Отправка уведомлений с помощью SMS А можно подобную подсказку но для отправки E-Mail?

dmw: А можно подобную подсказку но для отправки E-Mail? Встроенная функция перестала работать? http://smartliving.ru/Main/ProgrammingFunctions

Amarok: SendMail('alisa.kusanagi@gmail.com', 'blackky@gmail.com', 'subj', 'mail'); Абонент письмо не получил

witall: Доброго времени суток. Подскажите пожалуйста как сделать, чтобы вместо отправки SMS совершался голосовой вызов на определенный номер.

Anton_kulibin: У кого реализована отправка смс в убунту, у меня отправляет пустуе смс, т.е всетаки отправляет куда надо но пустые

dmw: viewtopic.php?p=4906#p4902 Делали все так? Если както по своему, то скорее всего проблема с русским языком, попробуйте отправить в латинице.

Anton_kulibin: Делал все копипастом. Самое интересное из консоли отправляет нормально даже с русскими буквами.

dmw: У вас скорее всего проблемы с кодировкой. Проверьте: - файл скрипта должен быть в utf8 - попробуйте послать в латинице - попробуйте только цифры - добавьте в код say($comand) и say($text) на время отладки.

Anton_kulibin: Вчера немного потренировался, ничего придумать не мог, сменил shell_exec на просто exec смски стали приходить с текстом. UPD. Да ты прав, видимо вчера редактировал из винды и сохранил файл в UTF8. Так что shell_exec тоже работает. СПС за подсказку

smoker_vvo: Господа, доброго времени суток. Подскажите как отправить более одного параметра.... Нужда в следующем, несколько раз в сутки мне надо получать, одной СМС, значения нескольких температурных и контрольных датчиков... У самого пока не получилось. МЖД установлен на Win.

Stunt: Доброго времени суток всем. Тоже застрял с настройкой уведомлений через SMS. Настраивал по этой инструкции - viewtopic.php?f=4&t=333#p4902 Чего добился: identify.jpg Модем определяется... test_sms.jpg SMS из консоли уходит и приходит адресату... И... Все. :( В smsgw модем прописал {
      $port = "/dev/ttyACM0"; //указать куда смонтировался модем
      $f = fopen ($port, "rw+");
      //Чтобы послать USSD запрос на номер *100#, команда должна выглядеть так:
      //AT+CUSD=1,"AA180C3602",15 (двойные кавычки обязательны)
      $text = "AT+CUSD=1,\"AA180C3602".encodePDU($phone)."\",15\r\n"; 
      fputs
($f, $text);
      while ($s = fgets($f)) {
       if (substr($s, 0, 5) == "+CUSD") {
        $codetext = substr(trim($s), 10, -4);
        $res = decodePDU($codetext);
        if (strpos($res, "1 - Dalee") !== false) {
         fputs($f, "AT+CUSD=1,".encodePDU("1").",15\r\n");
        }
 
Создал скрипт в корне сайта (как в инструкции) - тишина. Если запускать его из консоли - тоже тишина. Создал сценарий с проверкой баланса и записью результата в ThisComputer.Balance include_once(ROOT.'lib/hardware/smsgw.php');
 $res=sendUSD("*100#");
 if (preg_match('/(\d+,\d+)/is',$res,$m)) {
  $balance=floatval(str_replace(",",".",$m[1]));
  sg('ThisComputer.Balance', $balance);
 }
say("Баланс ".round(gg("ThisComputer.Balance"))." рублей");  balans.jpg И снова молчание. Запрос на баланс *100# Что я делаю не так? =)

dmw: С правами у вас все в порядке? viewtopic.php?f=4&t=333#p4906

Stunt: Да, права выставил.

Jager: Добавил в описание вариант с отправкой SMS уведомлений через сервис sms.ru http://smartliving.ru/Main/ScSMSGate

[ Обсудить на форуме ]

 

MajorDomo

Информация

Проекты

Партнёры

edit SideBar

 
 
 

 

Blix theme adapted by David Gilbert, powered by PmWiki