Receive SMS and Make call using AT command with SIM900

1.9k views Asked by At

I am having some difficulties with getting my python code working. I have Rpi2 with SIM900 module attach. I can make calls, receive call, send SMS even I can receive an SMS. But putting all together is giving me a headache. I have scroll over and over google and now I see that even results are all the time the same so I am at 0 point of getting further.

So my agenda is that I would send and SMS to SimModule. Python would read the incoming SMS's if SMS would arrive from phone No. from approved list and would contain specific code it would make a call to specific number:

Example of SMS

RV -> make call to cell no: 49
RI -> make call to cell no: 48
MV -> make call to cell no: 47
MI -> make call to cell no: 46

I got so far that I can read an SMS with the following code

import serial
import time
import sys


class sim900(object):

    def __init__(self):
        self.open()

    def open(self):
        self.ser = serial.Serial('/dev/ttyAMA0', 115200, timeout=5)

    def SendCommand(self,command, getline=True):
        self.ser.write(command)
        data = ''
        if getline:
            data=self.ReadLine()
        return data

    def ReadLine(self):
        data = self.ser.readline()
#        print data
        return data

    def GetAllSMS(self):
        self.ser.flushInput()
        self.ser.flushOutput()

        command = 'AT+CMGL=\"ALL\"\r'#gets incoming sms that has not been read
        print self.SendCommand(command,getline=True)
        data = self.ser.readall()
        print data
        self.ser.close()

    def Call49(self):
        self.ser = serial.Serial('/dev/ttyAMA0', 115200, timeout=5)
        self.ser.write('ATD49;\r')
        time.sleep(1)
        time.sleep(1)
        self.ser.write(chr(26))
           # responce = ser.read(50)
        self.ser.close()
        print "calling"

    def Call48(self):
        self.ser = serial.Serial('/dev/ttyAMA0', 115200, timeout=5)
        self.ser.write('ATD48;\r')
        time.sleep(1)
        self.ser.write(chr(26))
           # responce = ser.read(50)
        self.ser.close()
        print "calling"

h = sim900()
h.GetAllSMS()

I can read the SMS (see bellow)

AT+CMGL="ALL"
AT+CMGL="ALL"
+CMGL: 1,"REC READ","+30000000000","","17/08/27,23:28:51+08"
RV
+CMGL: 2,"REC READ","+30000000000","","17/08/28,00:34:12+08"
RI
OK

How can now I add function if in SMS "def GetAllSMS" phone number +30000000000 will exist together with text RV that it will execute "def Call48" if it will be RI it will execute "def Call47"

Some help would be appreciated. Tnx in advance.

1

There are 1 answers

5
9dogs On

Proper parsing of modem responses may be tricky (see this answer for example). If you are going to use messaging capability as well as voice calls and USSD-requests you'll probably end up recreating python-gsmmodem library :) But in your special case of parsing SMS response, you can use this code (adapted from mentioned python-gsmmodem).

import re

def GetAllSMS(self):

    self.ser.flushInput()
    self.ser.flushOutput()

    result = self.SendCommand('AT+CMGL="ALL"\r\n')
    msg_lines = []
    msg_index = msg_status = number = msg_time = None

    cmgl_re = re.compile('^\+CMGL: (\d+),"([^"]+)","([^"]+)",[^,]*,"([^"]+)"$')

    # list of (number, time, text)
    messages = []

    for line in result:
        cmgl_match = cmgl_re.match(line)
        if cmgl_match:
            # New message; save old one if applicable
            if msg_index != None and len(msg_lines) > 0:
                msg_text = '\n'.join(msg_lines)
                msg_lines = []
                messages.append((number, msg_time, msg_text))
            msg_index, msg_status, number, msg_time = cmgl_match.groups()
            msg_lines = []
        else:
            if line != 'OK':
                msg_lines.append(line)

    if msg_index != None and len(msg_lines) > 0:
        msg_text = '\n'.join(msg_lines)
        msg_lines = []
        messages.append((number, msg_time, msg_text))

    return messages

This function will read all SMS and return them as a list of tuples: [("+30000000000", "17/08/28,00:34:12+08", "RI"), ("+30000000000", "17/08/28,00:34:12+08", "RV")... Iterate over that list to check whether number is valid and take necessary action:

for number, date, command in messages:
    if number != "+30000000000":
        continue
    if command == 'RI':
        self.call_1()
    elif command == 'RV':
        self.call_2()