Страница 1 из 2

Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 27 май 2009, 15:13
phil_qwerty
ОС: Linux Ubuntu 8.04
Модем: Siemens MC35i терминальный

Хочется настроить смс-уведомления, посылаемые сервером, с помощью GSM модема.
При работе с модемом через minicom никаких проблем не возникает, модем прекрасно отвечает на AT команды и выполняет их.
Но, нужно это дело автоматизировать. Написал скрипт на пхп для этого дела. Но модем команды посланные со скрипта отрабатывает неправильно, он их как бы зацикливает, те отрабатывает по нескольку раз. Пример:
1. Вводит команду первый раз
ATZ
A

OK

2. Второй раз
TZATZ

OK
Как видно из примера, даже простую команду сброса модем пытается прочитать по второму разу,
естесственно при вводе следующей команды часть первой команды осталась в порту.
Сначала думал дело в скрипте, но порывся с инете, скачал несколько других вариантов, и та же самая проблема. Причем варианты рабочие. Те дело не в скрипте.
Вот вариант скрипта на питоне:
Код: Выделить всё
#!/usr/bin/env python

from os import path
from optparse import OptionParser
from sys import exit,stderr
import re

default_tty='/dev/ttyS0'

parser = OptionParser()

parser.add_option('-t','--tty',dest='tty',default=default_tty,help='tty file for sending. Default is:'+default_tty)
parser.add_option('-p','--phone',dest='phone',help='phone number for send msg')
parser.add_option('-m','--message',dest='message',help='Message for sending')
parser.add_option('-f','--file',dest='message_file',help='Text file with text message for sending')

option,args = parser.parse_args()

if not path.exists(option.tty):
    print >> stderr, "your tty file don't exists: '%s'" % option.tty
    exit(1)

if not option.message and not option.message_file:
    print >> stderr, "please give me a message or file for sending"
    exit(1)
elif not option.message:
    option.message = open(option.message_file).read()

if not option.phone:
    print >> stderr, "please give me a phone for send a message"
    exit(1)

regex = re.compile('^\+?[0-9]+$')
match = regex.match(option.phone)
if not match:
    print >> stderr, "invalid phone number: %s" % option.phone
    exit(1)

f = open(option.tty,'w')
f.write('AT+CMGS="'+option.phone+'"\n'+option.message+'\n%s' % chr(26))
f.close()

ВОПРОС: подскажите, почему при работе в minicom такого не происходит? И в чем вообще может быть проблема? Может нужна какая нибудь настройка ttyS*? Кто нибудь сталкивался вообще с таким?

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 27 май 2009, 15:33
lehisnoe
я, при кодинге, сталкивался с тем, что нужно вставлять маааленький (где-то в 0,1 сек) sleep между командами.

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 28 май 2009, 08:56
phil_qwerty
я понимаю, конечно, такие нюансики есть. но тут то проблема другая. я ведь беру рабочий скрипт))) и он на моей машине не работает(((
я конечно нашел альтернативный вариант, использую gnokii!!!! но хотелось бы разобраться в чем причина

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 28 май 2009, 12:06
root
а если попробовать на perl ?
я конечно не мега кодер, но работает :)
этот perl cкрипт шлет СМСки с сервера FreeBSD через com порт
используя порт:
Port: p5-Device-Modem-1.50
Path: /usr/ports/comms/p5-Device-Modem
Info: Perl class to interface generic modems (AT-compliant)
WWW: http://search.cpan.org/dist/Device-Modem/


Код: Выделить всё
#!/usr/bin/perl
use Device::Modem;
use Time::Local;
use DBD::mysql;

my $database="DB_NAME";
my $host="127.0.0.1";
my $password="DB_PASSWORD";
my $user="DB_USER";
my $port="3306";

my $dsn = "DBI:mysql:database=$database;host=$host;port=$port";
my $dbh = DBI->connect($dsn, $user, $password);

sub mys {
        my $q=shift;
        my $a;
        $a = $dbh->prepare($q);
        $a->execute;
        return $a;
}

my $debug=0;
my $debug2=0;

$pidfile="/var/run/sms_to_send.pid";
$pr=0;
open (TMP,"<$pidfile") or newpid();
if ($pr == 0){
        $op=<TMP>;
        $cmd=sprintf ("/bin/ps -ax | /usr/bin/grep -w '%d' | /usr/bin/grep -v 'grep'",$op);
        $op=`$cmd`;
        chomp($op);
        print $op;
        if ($op eq ""){
                #print "Override old PID\n";
                newpid();
        }else{
                print "Can't start: process already executed\n";
        }
}
close TMP;

sub newpid{
        $pr=1;
        open (PID,">$pidfile");
        print PID $$;
        close PID;
        start();
}

sub start {
    if ($debug){
        open(LOG,">>/usr/local/sbin/scripts/sms_to_send.log") or die "Can`t open log file...\n";
    }
    $kernhostname=`/sbin/sysctl -a | grep kern.hostname`;
    @hostname=split(' ',$kernhostname);
    $host=$hostname[1];
    chomp($host);
    $email='root;
    $prich='MC75 trouble!';
    $rep_serial='No connection with serial port!';
    $rep_at='AT commands not available!';
    $rep_mode='Can not set TEXT mode for sms';
    $at='AT';
    $at_pin='AT+CPIN=0000';
    $atmode="AT+CMGF=1";
    $at_mess='AT+CMGL=ALL';
    $at_del_mess='AT+CMGD=';

    $can_send=1;
    $qsel=mys("SELECT `id`,`msg`,`mobile`,`clients_id` FROM `sms_sended`
        WHERE `sended`='0' AND `send_date` IS NULL
        ORDER BY `priority` DESC");
    $fsms=$qsel->rows;
    if ($debug){
        if ($fsms>0){
            print "Found $fsms SMS to send...\n";
        }
    }
    my $modem = new Device::Modem( port => '/dev/cuad0', baudrate => '115200');
    if( $modem->connect( baudrate => 115200 ) ) {
        $connected=1;
        if ($debug){print LOG "connected!\n";}
        $modem->atsend( $at . Device::Modem::CR);
        $res_at=$modem->answer();
        if ($res_at eq "ERROR"){
            $can_send=0;
            system ("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_at '| sendmail $email");
        }else{
            #print "RES AT: $res_at\n";
        }
        $modem->atsend( $at_pin . Device::Modem::CR);
        $modem->answer();
        $modem->atsend( $atmode . Device::Modem::CR);
        $res_mode=$modem->answer();
        if ($res_mode eq "ERROR"){
            $can_send=0;
            system ("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_mode (ERROR|$res_mode) on first mode'| sendmail $email");
        }elsif ($res_mode eq "NO CARRIER"){
            $can_send=0;
            system ("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_mode (NO CARRIER)'| sendmail $email");
        }else{
            #print "RES AT MODE: $res_mode\n";
        }
    }else{
        $connected=0;
        $can_send=0;
        if ($debug){print LOG "sorry, no connection with serial port!\n";}
        system ("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_serial'| sendmail $email");
    }
    if ($connected && $can_send){
        while (@m=$qsel->fetchrow){
            if ($m[2] ne "" && $m[1] ne ""){
                if ($debug){
                    chop($date=`date "+%d.%m.%Y %H:%M:%S"`);
                    print LOG "$date\n";
                    print LOG "SMS ID:\t$m[0]\n";
                    print LOG "Client ID:\t$m[3]\n";
                    print LOG "Phone:\t$m[2]\n";
                    print LOG "Message: $m[1]\n";
                }
#####################
#Changes here
#####################
                if ($m[1]=~/^[\x0A\x0D\x20-\x7F]+$/){
                        $len=0;
                        if ($debug){
                                print LOG "Message @ Latin-1: $m[1]\n";
                        }
                }else{
                        $m[1]=cp1251_2ucs2($m[1]);
                        $mess="00";
                        $mess.="11";
                        $mess.="00";
                        $mess.="0B";
                        $mess.="91";
                        $m[2]=~s/\+//;
                        if ((length($m[2])/2)%2){
                                $m[2].="F";
                        }
                        for ($i=0;$i<length($m[2]);$i+=2){
                                $mess.=substr($m[2],$i+1,1).substr($m[2],$i,1);
                        }
                        $mess.="00";
                        $mess.="08";
                        $mess.="C1";
                        $mess.=sprintf("%02X",length($m[1])/2);
                        $mess.=$m[1];
#                       $mess.=chr(26);
                        $len=sprintf ("%s",(length($mess)-2)/2);
                        $m[1]=$mess;
                        if ($debug){
                                print LOG "Message [len: $len] @ CP1251: $m[1]\n";
                        }
                }
                $modem->atsend(sprintf("AT+CMGF=%d%s",$len?0:1,Device::Modem::CR));
                $res_mode=$modem->answer();
                if ($res_mode eq "ERROR"){
                        $can_send=0;
                        system (sprintf("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_mode (ERROR) on send command: %s'| sendmail $email",sprintf("A
                }elsif ($res_mode eq "NO CARRIER"){
                        $can_send=0;
                        system ("echo \'From:Mon_System\nTo:root\nSubject:Mon: $host - $prich\n\n $rep_mode (NO CARRIER) on send'| sendmail $email");
                }

                if (!$len){
                        $at_phone="AT+CMGS=".$m[2];
                }else{
                        $at_phone="AT+CMGS=".$len;
                }

#####################
#               $at_phone="AT+CMGS=".$m[2];
                $modem->atsend( $at_phone . Device::Modem::CR );
                $repl_phone=$modem->answer();
                if ($debug){print "Reply phone: =>[$repl_phone]<=\n";}
                if ($repl_phone eq "> "){
                    $modem->atsend( $m[1] . Device::Modem::CTRL_Z);
                    #+CMGS: %d
                    `/bin/sleep 2`;
                    #$repl_phone2=$modem->answer();
                    #print "\tReply phone2: =>[$repl_phone2]<=\n";
                    mys(sprintf("UPDATE `sms_sended` SET `error`='0', `sended`='1', `send_date`='%s' WHERE `id`='%d'",time(),$m[0]));
                    `/bin/sleep 3`;
                }else{
                    mys(sprintf("UPDATE `sms_sended` SET `error`='1' WHERE `id`='%d'",$m[0]));
                    print LOG "WARNING!!! No promt for entering SMS\n";
                    if ($debug){print "WARNING!!! No promt for entering SMS\n";}
                }
            }
        }
    }
    if ($connected){
        $modem->disconnect();
    }
    if ($debug){
        print LOG "\t con=>$connected || can_snd=>$can_send\n";
        print LOG "-----------------------------------------------------------------------------------------------\n";
        close LOG;
        print LOG2 "--------------------------------------------\n";
        close LOG2;
    }
}

sub cp1251_2ucs2 {
        my $str=shift;
        my $i;
        my $results;
        my $ucs2;

        for ($i=0;$i<length($str);$i++){
                $ord=ord(substr($str,$i,1));
                if (($ord) < 127){
                        $results = sprintf("%04X",$ord);
                }elsif ($ord eq 184){
                        $results="0451";
                }elsif ($ord eq 168){
                        $results="0401";
                }else{
                        $results = sprintf("%04X",($ord-192+1040));
                }
                $ucs2 .= $results;
        }
        return $ucs2;
}


скрипт тягает саму мессагу и номер мобилки из БД MySQL
названия полей говорят сами за себя

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 28 май 2009, 13:45
phil_qwerty
спасибо, попробую дома!!! думается мне нужно поменять в скрипте обращение к порту и с mysqlем посидеть немного.
будут результаты - отпишу

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 28 май 2009, 14:13
root
phil_qwerty писал(а):спасибо

пжлста

phil_qwerty писал(а):и с mysqlем посидеть немного

да не надо с ним сидеть
просто удали селекты из БД и замени их своими статическими значениями
ты с MySQL работал когда нить ?

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 28 май 2009, 14:47
phil_qwerty
конечно работал))) не углубленно, но знаю что такое селекты, джойнты и прочая лабуда.
да и постановка задачи у меня определяет вытаскивание телефона и месаги из БД, я правда хотел это сделать с помощью триггеров и хранимых процедур, но если Ваш скрипт на питоне отработает как надо, я откажусь от этой идеи

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 29 май 2009, 11:51
root
phil_qwerty писал(а):но если Ваш скрипт на питоне отработает как надо

1. он на perl :)
2. можно на ТЫ без проблем

табла MySQL у меня вот такая:

Код: Выделить всё
CREATE TABLE `sms_sended` (
  `id` bigint(20) NOT NULL auto_increment,
  `msg` varchar(160) default NULL,
  `sms_msg_type` smallint(1) NOT NULL default '0',
  `length` varchar(255) default NULL,
  `mobile` varchar(12) default NULL,
  `date` bigint(20) default NULL,
  `send_date` bigint(20) default NULL,
  `sended` smallint(1) NOT NULL default '0',
  `error` smallint(1) NOT NULL default '0',
  `priority` smallint(1) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `date` (`date`)
) TYPE=MyISAM;


немного подправил скрипт в моем сообщении выше, добавил "работу" с БД

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 01 июн 2009, 08:43
phil_qwerty
root писал(а):1. он на perl :)

сори )))
root писал(а):2. можно на ТЫ без проблем

можно))

сейчас разрулил отправку смс на баше, использовал gnokii, все буквально одной строкой, gnokii очень много умеет сам.
не стал изобретать велосипед вообщем то)))
сейчас на работе полегче стало, буду разбираться с твоим скриптом, тестить )))
посмотрим что быстрее работает)))

Re: Проблема со скриптом для управления GSM модемом

СообщениеДобавлено: 01 июн 2009, 11:44
root
phil_qwerty писал(а):сейчас разрулил отправку смс на баше

ну дык покажи как, интересно ж :)