Нужно отладить код. Прием СМС с парсингом суммы.

klbng
Offline
Зарегистрирован: 11.05.2021

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

Идея такова: СМС от сбербанка приходит на sim800l, нужно из текста СМС вытянуть сумму зачисления.
Сейчас код работает, но нестабильно. Если прислать несколько СМС подряд - вообще виснет. Есть мнение, что это из-за использования стрингов.

Вот кусок кода именно с приемом СМС.

001#include <SoftwareSerial.h>
002 
003SoftwareSerial gsm(8, 9); // RX, TX
004 
005unsigned long tm = 0, cur = 0;
006bool flag = 0, reg = 1;
007String msg = "";
008 
009void setup () {
010  Serial.begin(9600);
011  gsm.begin(19200);
012  gsm.flush();
013  gsm.println("at+cmgf=1;&W");delay(100);
014  gsm.println("at+cscs=\"gsm\";&W");delay(100);
015}
016 
017void loop () {
018  if (reg) {
019    reg = 0;
020    gsm.println("at+cmgl=\"rec unread\"");
021    delay(10);
022  }
023  if (gsm.available()) {
024    char inChar = gsm.read();
025    //Serial.write(inChar);
026    msg += inChar;
027    /*tm = millis();
028    msg = "";
029    do {
030      cur = millis();
031      if (gsm.available()) {
032        char inChar = gsm.read();
033        msg += inChar;
034      }
035      /*Serial.print(" ");
036      Serial.print(inChar, HEX);
037      Serial.print(" ");*/
038    tm = millis();
039    flag = 1;
040  }
041  if (flag && millis() - tm >= 7000) {
042    flag = 0;
043    msg.toLowerCase();
044    //Serial.println("MSG:" + msg);
045     
046    if (msg.indexOf("+cmti: \"sm\"") != -1 || msg.indexOf("+cmti: \"me\"") != -1) {
047      gsm.println("at+cmgl=\"rec unread\"");
048      delay(10);
049    }
050    if (msg.indexOf("at+cmgl=\"rec unread\"") != -1) {
051      String line = "";
052      byte row = 0;
053      for (int i = 0; i < msg.length(); i++) {
054        line += msg[i];
055        if (msg[i] == '\n') {
056          //Serial.println("row:" + String(row) + " str=" + line);
057          row++;
058          if (reg) {
059            reg = 0;
060            Serial.println(UCS2ToString(line));
061            String money = UCS2ToString(line);
062            if (money.indexOf("аеревад ") != -1) {
063              money = money.substring(money.indexOf("аеревад ") + 14, money.indexOf("р Б"));
064              //Serial.println("money:" + money);
065            } else if (money.indexOf("зачисаеаие ") != -1) {
066              money = money.substring(money.indexOf("зачисаеаие ") + 20, money.indexOf("р Б"));
067              //Serial.println("money:" + money);
068           }
069            Serial.println("money:" + String(money.toInt()));
070            gsm.println("at+cmgda=\"del read\"");
071          }
072          if (line.indexOf("+cmgl:") != -1) {
073            reg = 1;
074          }
075          line = "";
076        }
077      }
078    }
079     
080    msg = "";
081  }
082  if (Serial.available()) {
083    //while (Serial.available() > 0)
084    gsm.write(Serial.read());
085  }
086}
087 
088String UCS2ToString(String s) {                       // Функция декодирования UCS2 строки
089  String result = "";
090  unsigned char c[5] = "";                            // Массив для хранения результата
091  for (int i = 0; i < s.length() - 3; i += 4) {       // Перебираем по 4 символа кодировки
092    unsigned long code = (((unsigned int)HexSymbolToChar(s[i])) << 12) +    // Получаем UNICODE-код символа из HEX представления
093                         (((unsigned int)HexSymbolToChar(s[i + 1])) << 8) +
094                         (((unsigned int)HexSymbolToChar(s[i + 2])) << 4) +
095                         ((unsigned int)HexSymbolToChar(s[i + 3]));
096    if (code <= 0x7F) {                               // Теперь в соответствии с количеством байт формируем символ
097      c[0] = (char)code;
098      c[1] = 0;                                       // Не забываем про завершающий ноль
099    } else if (code <= 0x7FF) {
100      c[0] = (char)(0xC0 | (code >> 6));
101      c[1] = (char)(0x80 | (code & 0x3F));
102      c[2] = 0;
103    } else if (code <= 0xFFFF) {
104      c[0] = (char)(0xE0 | (code >> 12));
105      c[1] = (char)(0x80 | ((code >> 6) & 0x3F));
106      c[2] = (char)(0x80 | (code & 0x3F));
107      c[3] = 0;
108    } else if (code <= 0x1FFFFF) {
109      c[0] = (char)(0xE0 | (code >> 18));
110      c[1] = (char)(0xE0 | ((code >> 12) & 0x3F));
111      c[2] = (char)(0x80 | ((code >> 6) & 0x3F));
112      c[3] = (char)(0x80 | (code & 0x3F));
113      c[4] = 0;
114    }
115    result += String((char*)c);                       // Добавляем полученный символ к результату
116  }
117  return (result);
118}
119 
120unsigned char HexSymbolToChar(char c) {
121  if      ((c >= 0x30) && (c <= 0x39)) return (c - 0x30);
122  else if ((c >= 'A') && (c <= 'F'))   return (c - 'A' + 10);
123  else                                 return (0);
124}

 

Ищу исполнителя, готового довести до ума этот проект

man9913
Offline
Зарегистрирован: 19.03.2016

напишу заново корректно работающий скетч. 2000р, предоплата 50%, man9913@mail.ru

SAB
Offline
Зарегистрирован: 27.12.2016

Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу  общественности. Ур-ы.

klbng
Offline
Зарегистрирован: 11.05.2021

SAB пишет:

Где то год назад, пытались договориться со сбером, присылать в обратном квитке при оплате через телефон не имя отчество и букву фамилии, а номер телефона с которого был осуществлен перевод суммы. Получили отказ. Хотя всё ПО уже было написано под 590 модем. А идея была классная - автоматизация оплаты услуги, с пробитием (фискализацией) чека на конкретного человека и отсылки ему на телефон QRcoda или SMS от ОФД. Так жаль потраченных ресурсов. Это действие со стороны сбера даже не попадало под 157-ФЗ, сначала вроде согласились подумать, но потом, наверно, сказали себе, что нам и так не плохо живется, зачем делать какие то телодвижения. И очередной раз плюнули на просьбу  общественности. Ур-ы.

Уговаривал их слать СМС на транслите (типа старый телефон у меня) - не хотят. А фискализация мне не нужна ("уплачиваю" НПД).
Есть лайфхак - нужно к сберкарте привязать два номера телефона. При переводе на номер "1", на него приходит полный текст с отправителем и т.д. Номер "2" получает только СМС "зачисление 100500 рублей". Так для работы достаточно оперировать только с одним типом сообщений.

SAB
Offline
Зарегистрирован: 27.12.2016

Да хоть 10 номеров привязывай к карте. Для того, чтобы не печатать чек на бумажном носителе, ты должен этот чек привязать к конкретному клиенту (даже полное ФИО не катит). И при передаче чека к ОФД предоставить либо номер телефона данного человека, либо адрес его электронной почты. Никто, естественно, из клиентов не будет предоставлять таких данных о своём телефоне и тем более почте. Да и ввод пришлось бы организовывать как то, если бы даже нашлись желающие. Но для продавца, только тогда можно не печатать чек на бумаге, если он знает телефон либо почту клиента. А это сокращает расходы предпринимателей как минимум на 30000 рублей за точку. Плюс кто то должен постоянно следить за этим принтером чеков, обслуживать, ремонтировать, заправлять бумагу, - это ещё не маленькие деньги за год набегают. Вот от этого гемора и было придумана железка и написано ПО. Причем по квитку от банка, эта сумма выводилась на дисплей контроллера и клиент мог использовать её на получение услуги. По сути дела, предприниматель имел бесплатный экваринг не привязанный ни к одному банку, и это был ещё один большой плюс. Не израсходованный баланс клиент мог забирать на карту клиента(по UID в базу данных). Таким образом всё работает в автомате. Извините модераторы,  я здесь так подробно описал идею, в надежде, а вдруг здесь окажутся люди, приближенные к !!!!!! и доведут это до применения. Ведь все помнят, что с 1 июля 2021 года, закон (отложенный дважды) о применении кассовых аппаратов для всех окончательно вступает в силу. И после указанной даты принял деньги (не важно нал/безнал) обязан напечатать чек и передать его в ОФД. Да, и пока один не выданный чек штраф 10000 рублей. 10 чеков не распечатал, закрывай контору :). Вот так как то.

klbng
Offline
Зарегистрирован: 11.05.2021

rst пишет:

klbng пишет:
Если прислать несколько СМС подряд - вообще виснет. Есть мнение, что это из-за использования стрингов.
Я конечно не знаю что там в нижнем белье носил слившийся исполнитель - стринги или что-то ещё. Но думаю, что он, исходя из малости уплаченного вами ему гонорара, определил что вы - человек небогатый и поэтому вам в принципе не может приходить более одной подряд СМС-ки с суммами зачисления из банка.

Заплатили бы ему больше, он бы понял, что вы состоятельный чел, что вам запросто может и десяток СМС-зачислений подряд прилететь. И сделал бы поддержку в ПО.

На самом деле, о моём бедственном положении исполнитель вряд ли мог точно знать. И запрошенный гонорар был уплачен в стопроцентном размере до начала работы. Если кому-то интересно, то исполнитель - это известный в местных кругах "специалист" Звягинцев/Литвиненко/DIYquest...

UPD: несколько смс очень любит присылать МЧС. Ну и другого спама можно ожидать

sadman41
Offline
Зарегистрирован: 19.10.2016

Звягинцев ещё на плаву? Где клиентуру набирает?

klbng
Offline
Зарегистрирован: 11.05.2021

Я с ним имел год назад положительный опыт работы. Нашел через ВК

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Приведите пример смс.
Приём в латинице 2 недели 3000 рублей.
В PDU формате по русски от 5000 рублей.
50% предоплата. Зависать точно не будет, но конечно при правильной сборке схемы.
Andycat2013@yandex.ru