3

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.

user3343073
  • 75
  • 1
  • 9

1 Answers1

1

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()
9dogs
  • 1,446
  • 10
  • 18
  • HI I see that I maybe I did not rephrase my question correctly. I need to be able to read the following +CMGL: 2,"REC READ","+30000000000","","17/08/28,00:34:12+08" RI If the SMS would contain +30000000000 and RI python would make ATD0000001 call to the phone number. If the SMS would contain +30000000000 and RV python would make ATD0000002 call to the phone number. and so on. If criteria of RI, RV, MI, MV and phone number +30000000000 in SMS are not met function should do nothing – user3343073 Aug 28 '17 at 13:15
  • Sorry for the confusion I started on the wrong place trying to strip instead of just looking for a string in the SMS. – user3343073 Aug 28 '17 at 13:20
  • yep, you'll get messages list using that function and then do whatever you want with them. I updated an answer with use case for clarity. – 9dogs Aug 28 '17 at 13:33
  • Hi I have tried but the code did not work. I got no reply. I have modify the main question. If you could help. The idea is still the same I have just added two more "def Call49(self):" and def Call48(self): functions. Both functions work if I add them in the end of the script as h.Call48 or h.Call49. So is it now possible to read from GetALLSMS and execute if in the SMS phone number and text will be? – user3343073 Aug 28 '17 at 16:20
  • what exactly is the problem? `messages` var is empty? You are the only person who can debug this code, try to print vars step by step. – 9dogs Aug 28 '17 at 17:11