Read SMS text filter for credit value

Team,

Trying to do the following with a SIM7600.

Operator needs 2424 and BAL sent to retrieve the balance

Output using AT commands directly and all I want is the credit 20.05.

SMS text is at index 0 and +CMGRD=0 reads then deletes.

Couple of questions is I need to factor if there is any other random SMS from the operator so every x hrs I run modem.sendAT("+CMGD=0,4"); that deletes all SMS texts so I should be at index 0 again.

Thoughts? where I am going wrong? Its almost like code doesnt work and its only given me the credit value when the SMS is not deleted i.e, at a different index say 1 or 2.

Run the AT+CPMS? to see where the SMS is located - SIM, stop my +CMGD=0,4 command and SMS count builds as expected.


AT+CPMS?
+CPMS: "SM",0,10,"SM",0,10,"SM",0,10
+CPMS: "SM",1,10,"SM",1,10,"SM",1,10
+CPMS: "SM",3,10,"SM",3,10,"SM",3,10

AT commands are

AT+CMGF=1
AT+CMGS="2424"
BAL
CTRL-Z

Output from the AT+CPMS 2424 BAL command

18:37:16.135 -> AT+CMGS="2424"
18:37:16.135 -> 
18:37:16.135 -> > 
18:37:22.475 -> 
18:37:22.475 -> +CMGS: 201
18:37:22.521 -> 
18:37:22.521 -> OK
18:37:22.521 -> +CMGS Sent BALANCE request!!!
18:37:22.521 -> AT+CMGL="REC UNREAD"
18:37:22.993 -> 
18:37:22.993 -> +CMGL: 1,"REC UNREAD","2424","","23/07/12,18:33:17+48"
18:37:23.089 -> Hi! Your Skinny balance is
18:37:23.183 -> $20.05 credit

Code block that was working and randomly works. Well I think it works when it finds a old SMS at index 0.

//Get Balance send to display on boot
void Get_Balance()
{
  if (balance_requested) {                                    
    //Serial.println("Balance has already been requested!");
    return;                                                   
  }
  
  String smsNumber = "2424";                
  String smsMessage2 = "BAL";               

  //Set in global
  //modem.sendAT("+CMGF=1");            
  //modem.waitResponse(1000L);

  String command = "+CMGS=\"" + smsNumber + "\"";
  modem.sendAT(command);
  modem.waitResponse(1000L);
  SerialAT.print(smsMessage2);                                
  modem.waitResponse(1000L);
  SerialAT.write(CR);                                   
  modem.waitResponse(5000L);
  pDBGln("+CMGS Sent BALANCE request!!!");

  //modem.sendAT("+CMGL=\"ALL\"");                              
  //modem.waitResponse(120000L);                                  
  modem.sendAT("+CMGL=\"REC UNREAD\""); 
  modem.waitResponse(5000L);                          
  modem.sendAT("+CMGRD=0");                         
  data = SerialAT.readString();
  Serial.print("message: ");
  Serial.println(data);

  String balanceMessage = data.substring(data.indexOf("$"));  
  balanceMessage.trim();                                      
  float balance = balanceMessage.substring(1).toFloat();      
  Serial.print("Get balance: ");
  Serial.println(balance);
  credit = balance;
  mqtt.publish(topicCredit, String(balance).c_str());
  balance_requested = true;                                   
}
OK
AT+CMGF=1
OK
AT+CMGS="2424"
> 
BAL
> 
> 
+CMGS: 246
OK
+CMTI: "SM",0

+CMTI response takes 10-12 secs or 1-2 secs

0 – No SMS-DELIVER indications are routed to the TE.
1 – If SMS-DELIVER is stored into ME/TA, indication of the
memory location is routed to the TE using unsolicited result code:
+CMTI: <mem3>,<index>

If I use the AT manual commands to get the credit SMS the code and dont delete it the next time it picks it up and gets the credit value of 19.35 which is correct but to me this means the this code is not working and the logs at the bottom show it picked up on a previous SMS at index 0?

  String command = "+CMGS=\"" + smsNumber + "\"";
  modem.sendAT(command);
  modem.waitResponse(1000L);
  SerialAT.print(smsMessage2);                                
  modem.waitResponse(1000L);
  SerialAT.write(CR);                                   
  modem.waitResponse(5000L);
  pDBGln("+CMGS Sent BALANCE request!!!");

  //modem.sendAT("+CMGL=\"ALL\"");                              
  //modem.waitResponse(120000L);                                  
  modem.sendAT("+CMGL=\"REC UNREAD\""); 
  modem.waitResponse(5000L);                          
  modem.sendAT("+CMGRD=0");                         
  data = SerialAT.readString();
  Serial.print("message: ");
  Serial.println(data);
19:44:42.906 -> AT+CMGS="2424"
19:44:42.906 -> 
19:44:42.906 -> > 
19:44:45.252 -> 
19:44:45.252 -> +CMGS: 247
19:44:45.252 -> 
19:44:45.252 -> OK
19:44:45.299 -> +CMGS Sent BALANCE request!!!
19:44:45.299 -> AT+CMGL="REC UNREAD"
19:44:45.299 -> 
19:44:45.299 -> OK
19:44:45.299 -> AT+CMGRD=0
19:44:46.374 -> message: 
19:44:46.374 -> +CMGRD: "REC READ","2424","","23/07/13,19:42:38+48"
19:44:46.374 -> Hi! Your Skinny balance is
19:44:46.374 -> $19.35 credit
19:44:46.374 -> For your account info, text INFO to 2424.
19:44:46.419 -> 
19:44:46.419 -> OK

Can someone educate me as I dont understand where I am going wrong?

That seems a bad approach - how do you know that those texts don't contain stuff you need?

Why don't you just use the +CMTI unsolicited response to tell you when a new message arrives?

Not sure need some guidance, document for the SIM 7600 doesn't mention much.

The rules for storing received SMS depend on its data coding
scheme, preferred memory storage (AT+CPMS) setting and this
value:
0 – No SMS-DELIVER indications are routed to the TE.
1 – If SMS-DELIVER is stored into ME/TA, indication of the
memory location is routed to the TE using unsolicited result code:
+CMTI: <mem3>,<index>.
2 – SMS-DELIVERs (except class 2 messages and
messages in the message waiting indication group (store
message)) are routed directly to the TE using unsolicited result
code

What you've quoted is about storage - you need to look at notifications for when a message arrives.

Search the document for "CMTI" ?

Can you give a link to the document?

Thanks its mentioned once which is the excerpt above.

image

So give that a try.

As always, try this & other experiments manually on a terminal - don't try coding it until you've got familiar with it manually!

So AT+CNMI=2,1

+CMTI: "SM",0
+CMTI: "SM",1
+CMTI: "SM",2

Counts up as there are more SMS (x3)

AT+CMGD=0,4 now AT+CNMI=2,1 returns OK

So I need to send the SMS text 2424 with BAL then wait for AT+CNMI=2,1 to return +CMTI: "SM",0 or higher then AT+CMGR=0 and then filter the result.

Not quite:

AT+CNMI=2,1 enables the unsolicited responses - it's a setup that you only do once.

The +CMTI: responses then appear unsolicited - ie, without you having to issue a command to get (or "solicit") them.

So you send your message, then wait for a +CMTI: to indicate that a message (hopefully, the reply) has been received.

Funny thing was I had AT+CNMI=2,1 enabled once as you confirmed and had forgotten about it.

Check Balance requests the balance SMS message be sent.

void Check_Balance()
{
  CheckBalanceCount++;                         //Increment x by one and returns the old value of x
  String smsNumber = "2424";                   //Skinny is the Operator
  String smsMessage2 = "BAL";                  //Request the balance of the account

  if (CheckBalanceCount >= 28800) {            //Check balance every 2 hrs 7200, 8 hrs 28800, once a day 86400, or per week 604800 
    CheckBalanceCount = 0;

    String command = "+CMGS=\"" + smsNumber + "\"";
    modem.sendAT(command);
    modem.waitResponse(1000L);
    SerialAT.print(smsMessage2);               //Write the SMS message
    modem.waitResponse(1000L);
    SerialAT.write(CR);                        //Send the Ctrl+Z character to terminate the message
    modem.waitResponse(5000L);
    pDBGln("+CMGS Sent daily balance request!");
  }
}

Then every x minutes I call Read_SMS()

void Read_SMS() {
  static int checkCount = 0;
  checkCount++;
   if (checkCount >= 60) {  // Check every 60 seconds
    checkCount = 0;
    Serial.println("Checking for incoming SMS messages...");
    modem.sendAT("+CMGL=\"REC UNREAD\"");
    String response = SerialAT.readString();

   if (response.indexOf("+SMS FULL") != -1) {
      Serial.println("SMS memory full, deleting oldest message...");
      modem.sendAT("+CPMS?");     // +CPMS: "SM",10,10,"SM",10,10,"SM",10,10
      modem.waitResponse(5000L);
      return;
    }

   //Send SMS Skinny Balance Check 
   if (response.indexOf("Hi! Your Skinny balance is") != -1) {
      modem.sendAT("+CMGR=0");
      String messageContent = SerialAT.readString();  
      Serial.println("Message content: " + messageContent);  
      Serial.println("SMS: Skinny Balance Check");

      modem.sendAT("+CMGR=0");                                   //Send AT+CMGR command to read the SMS message at index 1 then deletes it
      data = SerialAT.readString();
      Serial.print("message: ");
      Serial.println(data);

      String balanceMessage = data.substring(data.indexOf("$"));  //Extract portion of message that contains balance
      balanceMessage.trim();                                      //Remove any leading/trailing white space
      float balance = balanceMessage.substring(1).toFloat();      //Extract numeric value of balance
      Serial.print("Get balance: ");
      Serial.println(balance);
      credit = balance;
      mqtt.publish(topicCredit, String(balance).c_str());

   //Delete the read message
      modem.sendAT("+CMGD=0");
      modem.waitResponse(1000L);
 }

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.